-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Description
TypeScript Version: 4.0.5
Search Terms:
generic inferring destructing function parameter
Description
I declared generic function with two generic types. One is depended on the other by keyof. Function takes one argument that is destructing and described by one interface (also generic). One of the parameters should be key of other one.
When I pass object with only these two depended properties TS throw confusing error.
After passing all properties to that object TS not complainig about this any more.
Moreover, if I change function to take seperate arguments (with the same typings) there is no such error.
Expected behavior:
Should throw error telling me that passed parameter is not assignable to interface ListProps, because it don't implement third property.
Moreover, TS is not inferring types of first two properties - I think it should.
Actual behavior:
There is confusing error after passing two of three properties with object as function argument:
Type 'string' is not assignable to type 'never'.(2322)
input.tsx(3, 3): The expected type comes from property 'itemKey' which is declared here on type 'ListProps<unknown, never>'
Related Issues:
Code
export interface ListProps<T, K extends keyof T> {
items: T[];
itemKey: K;
prop: number
}
export const Component = <T, K extends keyof T>({
items,
itemKey,
prop,
}: ListProps<T, K>) => {}
// throws confusing error
Component({items: [{name:' string'}], itemKey: 'name'})
// work after passing last property
Component({item: {name:' string'}, itemKey: 'name', prop: 1})
// work as expected without parameter destructing
export const Component2 = <T, K extends keyof T>(items: T[],
itemKey: K,
prop: number) => {}
// throws 'Expected 3 arguments, but got 2.'
Component2([{name:' string'}], 'name')Output
export const Component = ({ items, itemKey, prop, }) => { };
Component({ items: [{ name: ' string' }], itemKey: 'name' });Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}Playground Link: Provided