Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic inference incorrect #21571

Closed
charsleysa opened this issue Feb 2, 2018 · 4 comments
Closed

Generic inference incorrect #21571

charsleysa opened this issue Feb 2, 2018 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@charsleysa
Copy link

TypeScript Version: 2.7.1

Search Terms: inferred generic key type index

Code

interface IColumn<Row, Name extends keyof Row> {
    property?: Name;
    type?: Row[Name];
}

interface ITable<Row> {
    columns: Array<IColumn<Row, keyof Row>> | Array<keyof Row>;
}

declare function createTable<T>(definition: ITable<T>): T;

// Test1
const t1: { hello: string, goodbye: boolean } = createTable({
    columns: ['hello', 'goodbye']
});

// Test2
const t2: { hello: string, goodbye: boolean } = createTable({
    columns: [
        {
            property: 'hello'
        },
        {
            property: 'goodbye'
        }
    ]
});

Expected behavior:
Both Test1 and Test2 should correctly work with correct type inference on both sides.

Actual behavior:
Both Test1 and Test2 work correctly in TS2.6.2

In TS2.7.1 Test1 works correctly but is missing type inference on right side (hovering over createTable produces:

function createTable<{
    hello: any;
    goodbye: any;
}>(definition: ITable<{
    hello: any;
    goodbye: any;
}>): {
    hello: any;
    goodbye: any;
}

In TS2.7.1 Test2 does not work at all producing the following error:

[ts]
Argument of type '{ columns: ({ property: "hello"; } | { property: "goodbye"; })[]; }' is not assignable to parameter of type 'ITable<{ hello: any; }>'.
  Types of property 'columns' are incompatible.
    Type '({ property: "hello"; } | { property: "goodbye"; })[]' is not assignable to type 'IColumn<{ hello: any; }, "hello">[] | "hello"[]'.
      Type '({ property: "hello"; } | { property: "goodbye"; })[]' is not assignable to type '"hello"[]'.
        Type '{ property: "hello"; } | { property: "goodbye"; }' is not assignable to type '"hello"'.
          Type '{ property: "hello"; }' is not assignable to type '"hello"'.

Playground Link:
http://www.typescriptlang.org/play/#src=interface%20IColumn%3CRow%2C%20Name%20extends%20keyof%20Row%3E%20%7B%0D%0A%20%20%20%20property%3F%3A%20Name%3B%0D%0A%20%20%20%20type%3F%3A%20Row%5BName%5D%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20ITable%3CRow%3E%20%7B%0D%0A%20%20%20%20columns%3A%20Array%3CIColumn%3CRow%2C%20keyof%20Row%3E%3E%20%7C%20Array%3Ckeyof%20Row%3E%3B%0D%0A%7D%0D%0A%0D%0Adeclare%20function%20createTable%3CT%3E(definition%3A%20ITable%3CT%3E)%3A%20T%3B%0D%0A%0D%0A%2F%2F%20Test1%0D%0Aconst%20t1%3A%20%7B%20hello%3A%20string%2C%20goodbye%3A%20boolean%20%7D%20%3D%20createTable(%7B%0D%0A%20%20%20%20columns%3A%20%5B'hello'%2C%20'goodbye'%5D%0D%0A%7D)%3B%0D%0A%0D%0A%2F%2F%20Test2%0D%0Aconst%20t2%3A%20%7B%20hello%3A%20string%2C%20goodbye%3A%20boolean%20%7D%20%3D%20createTable(%7B%0D%0A%20%20%20%20columns%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20property%3A%20'hello'%0D%0A%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20property%3A%20'goodbye'%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%5D%0D%0A%7D)%3B

Related Issues:
Possibly
#21553
#21529

@zaclummys
Copy link

@charsleysa,
Have you tried to get feedback in a specific forum? stackoverflow.com will give you better and faster feedback for your problem. Check there if it's just a code error.

@mhegazy
Copy link
Contributor

mhegazy commented Feb 2, 2018

Looks like a duplicate of #21553

@mhegazy mhegazy added the Duplicate An existing issue was already created label Feb 2, 2018
@charsleysa
Copy link
Author

Current workaround for the issue is to not rely on the inference to build the type so Test2 becomes

// Test2
const t2 = createTable<{ hello: string, goodbye: boolean }>({
    columns: [
        {
            property: 'hello'
        },
        {
            property: 'goodbye'
        }
    ]
});

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants