Skip to content

Type infomation is missed when recursively use generic type & interface #23706

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

Closed
xcatliu opened this issue Apr 26, 2018 · 4 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@xcatliu
Copy link

xcatliu commented Apr 26, 2018

TypeScript Version: 2.8.3

Search Terms: type keyof extra

Code

type Template<T> = {
    [K in keyof T]: Template<T[K]>;
} & {
    __name?: string;
}

const template: Template<{
    foo: number;
    bar: {
        baz: string;
    }
}> = {
    foo: 1,
    __name: 'n',
    bar: {
        baz: 'b',
        not_exist_key: true
    }
};

Expected behavior: Should report error: 'not_exist_key' does not exist in type 'Template<{ baz: string; }>'

Actual behavior: No errors

Playground Link: playground

Related Issues:

@jack-williams
Copy link
Collaborator

jack-williams commented Apr 26, 2018

Edit: I think this is probably related to #13813

I think this is do to with excess property checking. Here is a smaller example:

type A = { x: { y: string } };
let x: A = { x: { y: "hello", z: true } }; // Good - Error. z is excess

type B = A & { extra: number; }
let y: B = { x: { y: "hello", z: true }, extra: 42 }; // Bad - No error (z is still excess).

I believe the issue is that excess property checking happens at one level at a time. After the first level TypeScript sees the intersection type and no longer marks the source type as a fresh object literal, which then disables excess property checking for the second level (properties y and z).

@xcatliu
Copy link
Author

xcatliu commented Apr 26, 2018

@jack-williams Thanks for your reply. The smaller example make this issue clearer.
Another question is why can't I add an extra key to mapped types like this:

type Template<T> = {
    [K in keyof T]: Template<T[K]>;
    foo?: string;
}
// Cannot find name 'foo'.
// '}' expected.

@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 26, 2018
@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2018

Duplicate of #13813. thanks @jack-williams!

@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 31, 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