io-ts recursion use issue - javascript

I trying to use t.recursion of io-ts library to document a type, that has recursion.
The type in documentation looks like this:
export interface BoxBase {
id?: string;
mode: DockMode;
size?: number;
children: (BoxBase | PanelBase)[];
}
I wrote this:
const PanelBaseV = t.intersection([
t.type({
tabs: t.array(TabBaseV),
}),
t.partial({
// ...
})
])
interface BoxBaseV {
mode: t.TypeOf<typeof DockModeV>,
children: Array<BoxBaseV | t.TypeOf<typeof PanelBaseV>>,
id?: Id,
size?: number,
}
const BoxBaseV: t.Type<BoxBaseV> = t.recursion('BoxBaseV', (self) =>
t.intersection([
t.type({
mode: DockModeV,
children: t.array(
t.union([ self, PanelBaseV ])
),
}),
t.partial({
id: IdV,
size: t.number,
})
])
)
Then I get an error in IDE:
Type 'LayoutBase' is not assignable to type '{ dockbox: BoxBaseV; } & { floatbox?: BoxBaseV | undefined; windowbox?: BoxBaseV | undefined; maxbox?: BoxBaseV | undefined; }'.
  Type 'LayoutBase' is not assignable to type '{ dockbox: BoxBaseV; }'.
    The types of 'dockbox.children' are incompatible between these types.
      Type '(BoxBase | PanelBase)[]' is not assignable to type '(BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; }))[]'.
        Type 'BoxBase | PanelBase' is not assignable to type 'BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; })'.
          Type 'BoxBase' is not assignable to type 'BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; })'.
            Type 'BoxBase' is not assignable to type 'BoxBaseV'.
              Types of property 'children' are incompatible.                 Type '(BoxBase | PanelBase)[]' is not assignable to type '(BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; }))[]'.
                  Type 'BoxBase | PanelBase' is not assignable to type 'BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; })'.
                    Type 'BoxBase' is not assignable to type 'BoxBaseV | ({ tabs: { id: string; }[]; } & { id?: string | undefined; size?: number | undefined; oldSize?: number | undefined; activeId?: string | undefined; alwaysOnTop?: boolean | undefined; ... 4 more ...; h?: number | undefined; })'.
Cannot understand, why 'BoxBase' is not assinable to type 'BoxBase | ({ tabs: { id: string; }[]; }...' (the last line) and how to fix the problem?

Related

Typescript error for Icon from react-native-elements

I am getting a typescript error when I try to use icons from react-native-elements.
This is the error.
Property 'tvParallaxProperties' is missing in type '{ type: string; name: string; color: string; size: number; }' but required in type 'Pick<IconButtonProps & { type?: string | undefined; Component?: typeof Component | undefined; reverse?: boolean | undefined; raised?: boolean | undefined; containerStyle?: StyleProp<...>; ... 5 more ...; brand?: boolean | undefined; } & Partial<...>, "backgroundColor" | ... 68 more ... | "brand">'.
Versions:
"react-native": "^0.64.1",
"react-native-elements": "^3.4.1",
How can I fix this error?

Property 'cursor' does not exist on type X, null or undefined, using generated graphql type with Svelte #each

I was using SvelteKit without the amazing "strict": true in tsconfig.json until today.
I have this code generated (with codegen) from a Graphql schema that I cannot change:
export type PlayerListQuery = {
__typename?: "Query";
playerList: {
__typename?: "PlayerConnection";
edges?: Array<{
__typename?: "PlayerEdge";
cursor: any;
node?: {
__typename?: "Player";
name?: string | null;
age?: number | null;
id: string;
} | null;
} | null> | null;
pageInfo: {
__typename?: "PageInfo";
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor?: any | null;
endCursor?: any | null;
};
};
};
which comes from this:
type PlayerConnection {
totalCount: Int!
pageInfo: PageInfo!
edges: [PlayerEdge]
}
type PlayerEdge {
cursor: Cursor!
node: Player
}
and I'm using it like this in Svelte:
{#each $store.data.playerList.edges || [] as { cursor, node } (cursor)}
{node?.name || "No name"}
<br>
{node?.age || "No age"}
{:else}
Empty array!
{/each}
Now with the strict option the error is:
(parameter) cursor: any
Property 'cursor' does not exist on type '{ __typename?: "PlayerEdge" | undefined; cursor: any; node?: { __typename?: "Player" | undefined; name?: string | null | undefined; ... more ...; | undefined; } | null | undefined; } | null'.ts(2339)
both for cursor and node because it's right, they can be null or undefined.
What do you suggest to fix this?

TypeScript: Type 'any' is not assignable to type 'never'

I have following type:
export type FormField = {
name: string;
type: string;
mandatory: boolean;
options?: FormFieldOptionsType;
visibleIfIndIsVisible?: number;
ind?: number;
value?: string;
dateCreatedAt?: string;
selectItemOtherArbitraryValueEnable?: boolean;
regex?: string;
defaultFormFieldOptionId?: string;
};
Assign one value like this
const saveFormField = (key: keyof FormField, value: any) => {
let formField: FormField = {
name: reloadProps?.formField?.name ?? "",
type: reloadProps?.formField?.type ?? "",
mandatory: reloadProps?.formField?.mandatory ?? false,
regex: reloadProps?.formField?.regex ?? "",
selectItemOtherArbitraryValueEnable:
reloadProps?.formField?.selectItemOtherArbitraryValueEnable,
};
formField[key] = value;
but yarn build raise an error, do you know why?
./pages/[lang]/formFieldOptions/[...eventId_formFieldId].tsx:125:55
Type error: Cannot find name 'valueof'.
123 | };
124 |
> 125 | const saveFormField = (key: keyof FormField, value: valueof FormField) => {
| ^
If I use following signature:
const saveFormField = (
key: keyof FormField,
value: FormField[keyof FormField]
) => {
error is sligthly different:
./pages/[lang]/formFieldOptions/[...eventId_formFieldId].tsx:137:5
Type error: Type 'string | number | boolean | FormFieldOptionsType | undefined' is not assignable to type 'never'.
Type 'undefined' is not assignable to type 'never'.
135 | reloadProps?.formField?.selectItemOtherArbitraryValueEnable,
136 | };
> 137 | formField[key] = value;
| ^
Strange with your latest edit I got this error. I thought e.target.value is string, seems not?!
./pages/[lang]/formFieldOptions/[...eventId_formFieldId].tsx:241:48
Type error: Property 'value' does not exist on type 'EventTarget & Element'.
239 | }}
240 | onBlur={(e: React.FocusEvent) =>
> 241 | saveFormField("name", e.target.value)
| ^
242 | }
This would give you a union type containing all possible types inside FormField.
export function saveFormField<T extends keyof FormField>(
key: T, value: FormField[T]
){
...
}

How to define an array with conditional elements in TypeScript?

I actually have no idea about this one :O
JS - Valid
interface Claim {
tractableClaimId: string;
clientClaimId: string;
accidentId: string;
clientId: string;
createdAt: Date;
dateOfAccident: Date;
policyHolderSessionId: string;
status: string;
actions: string;
estimate?: Estimate;
}
const [claims, setClaims] = useState<Claim[]>([]);
const claims = ['jamie']
const isSearchOrFilter = true;
[
...(isSearchOrFilter ? claims : []),
...['hutber']
]
//Output: (2) ["jamie", "hutber"]
Ts Error
Type 'false | Claim[]' is not an array type. TS2461
67 | });
68 | setClaims([
> 69 | ...(isSearchOrFilter ? claims : []),
| ^
70 | ...['hutber']
71 | ]);

Typescript - Types of parameters 'artifact' and 'value' are incompatible

I am trying to map over an array response from my API in Vue JS and I am getting a typescript error when doing so. Here is my code:
methods: {
export interface WebspaceBackupArtifact {
readonly date?: string;
readonly name?: string | null;
readonly path?: string | null;
readonly type?: string | null;
}
interface WebspaceBackupArtifactExtended extends WebspaceBackupArtifact {
size?: number;
type?: string;
}
let artifacts = [] as WebspaceBackupArtifactExtended[];
if (response?.data?.artifacts) {
artifacts = response.data.artifacts
.map((artifact: WebspaceBackupArtifactExtended) => ({
...artifact,
date: moment(artifact.date!).format('DD-MMM-YYYY'),
}))
.sort(
(
a: WebspaceBackupArtifactExtended,
b: WebspaceBackupArtifactExtended,
) => a.type!.localeCompare(b.type!),
);
}
}
produces the following error:
ERROR in /app/src/views/BackupAndRestore/BackupAndRestoreWebspaceBackup.vue(594,16):
my-project | 594:16 Argument of type '(artifact: WebspaceBackupArtifactExtended) => { date: string; size?: number | undefined; type?: string | undefined; name?: string | null | undefined; path?: string | null | undefined; }' is not assignable to parameter of type '(value: WebspaceBackupArtifact, index: number, array: WebspaceBackupArtifact[]) => { date: string; size?: number | undefined; type?: string | undefined; name?: string | ... 1 more ... | undefined; path?: string | ... 1 more ... | undefined; }'.
my-project | Types of parameters 'artifact' and 'value' are incompatible.
my-project | Type 'WebspaceBackupArtifact' is not assignable to type 'WebspaceBackupArtifactExtended'.
my-project | Types of property 'type' are incompatible.
my-project | Type 'string | null | undefined' is not assignable to type 'string | undefined'.
my-project | Type 'null' is not assignable to type 'string | undefined'.
my-project | 592 | if (response?.data?.artifacts) {
my-project | 593 | artifacts = response.data.artifacts
my-project | > 594 | .map((artifact: WebspaceBackupArtifactExtended) => ({
my-project | | ^
my-project | 595 | ...artifact,
my-project | 596 | date: moment(artifact.date!).format('DD-MMM-YYYY'),
my-project | 597 | }))
I have tried looking at other similar questions that have a similar error message but didn't manage to extract any valuable information that would help me in this case so I am not sure what I am doing wrong.
Am I maybe extending the interface wrong?
The error message is saying that you have a callback which requires a WebspaceBackupArtifactExtended but your response.data.artifacts array is an array of WebspaceBackupArtifact.
The extended version is assignable to the base version, but not vice-versa. The specific reason is the property type. WebspaceBackupArtifact allows string | null while WebspaceBackupArtifactExtended only allows string.
response.data.artifacts is not given a type in the code that you've provided, but I can tell that it is WebspaceBackupArtifact[] | undefined based on the error message. One thing you can do is remove the WebspaceBackupArtifactExtended annotations in your map and sort callbacks and let it be inferred from the array type.
You might also want to think about how to better handle handle instances where .date and .type are not defined rather than asserting that they will be defined.

Categories