Updatable list elements are not assignable to themselves
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
I have a component, with:
1. `useFragment` reading list of elements
2. mutation pushing a new element in updater
```tsx
// IN RENDER:
const mediaListCollection = useFragment(
graphql`
fragment AddToList_mediaListCollection on MediaListCollection {
lists {
...AddToList_updatable
status
entries {
id
...AddToList_assignable
}
}
}
`,
mediaListCollectionKey
)
// MUTATION:
{
updater: (store, response) => {
for (const list of mediaListCollection.lists ?? []) {
if (list != null && list.status === source.status) {
const { updatableData } =
store.readUpdatableFragment(
graphql`
fragment AddToList_updatable on MediaListGroup @updatable {
entries {
id
...AddToList_assignable
}
}
`,
list
)
if (response?.SaveMediaListEntry != null) {
updatableData.entries = [
...(list.entries?.filter((entry) => entry != null) ?? []),
response.SaveMediaListEntry,
]
}
}
}
}
}
```
I've noticed `useFragment` is causing performance issue and it doesn't have to read during render so I've moved it into the updater.
```tsx
// AFTER REFACTOR:
{
updater: (store, response) => {
const { updatableData: mediaListCollection } =
store.readUpdatableFragment(
graphql`
fragment AddToList_mediaListCollection on MediaListCollection
@updatable {
lists {
status
entries {
id
...AddToList_assignable
}
}
}
`,
mediaListCollectionKey
)
for (const list of mediaListCollection.lists ?? []) {
if (list != null && list.status === source.status) {
if (response?.SaveMediaListEntry != null) {
list.entries = [
...(list.entries?.filter((entry) => entry != null) ?? []),
response.SaveMediaListEntry,
]
}
}
}
}
}
```
But now I get a type error when setting:
```
Type '{ readonly id: string; } | null | undefined' is not assignable to type '{ readonly __typename: "MediaList"; readonly __id: string; readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">; }'.
```
New generated type is missing `__typename` and `__id` fields:
```ts
export type AddToList_mediaListCollection$data = {
get lists(): ReadonlyArray<{
status: MediaListStatus | null | undefined;
get entries(): ReadonlyArray<{
readonly id: string; // <-- HERE ONLY ID IS GENERATED
} | null | undefined> | null | undefined;
set entries(value: ReadonlyArray<{
readonly __typename: "MediaList";
readonly __id: string;
readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">;
}>);
} | null | undefined> | null | undefined;
set lists(value: []);
readonly " $fragmentType": "AddToList_mediaListCollection";
};
```
The OLD one is:
```ts
export type AddToList_mediaListCollection$data = {
readonly lists: ReadonlyArray<{
readonly $updatableFragmentSpreads: FragmentRefs<"AddToList_updatable">;
readonly entries: ReadonlyArray<{
readonly __typename: "MediaList";
readonly __id: string;
readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"AddToList_assignable">;
} | null | undefined> | null | undefined;
readonly status: MediaListStatus | null | undefined;
} | null | undefined> | null | undefined;
readonly " $fragmentType": "AddToList_mediaListCollection";
};
```
There's an easy workaround by selecting these missing fields manually
```
__typename
__id
```
This makes it work without runtime error, just the typescript error because the `AddToList_assignable` spread is missing
relay-compiler: 21.0.1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in relay-compiler 21.0.1 by reproducing the shown @updatable fragment and assignable spread with the generated TypeScript types. Trace how the compiler handles nested updatable fields and fragment spreads; done means the generated entries setter accepts the assignable fragment type while retaining __typename and __id without manual selections.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100