Skip to content

Wrong type inferring invoking generic function with parameter destructing #42030

@mszkudelski

Description

@mszkudelski

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions