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

Recursive mapped conditional types not working when using interfaces (regression between 3.3.3 and 3.5.1) #50749

Closed
ItsaMeTuni opened this issue Sep 13, 2022 · 2 comments

Comments

@ItsaMeTuni
Copy link

ItsaMeTuni commented Sep 13, 2022

Bug Report

πŸ”Ž Search Terms

recursive mapped conditional types interface generic

πŸ•— Version & Regression Information

  • This changed between versions 3.3.3 and 3.5.1

⏯ Playground Link

Playground link with relevant code (version 3.3.3, working as intended)

Playground link with relevant code (version 3.5.1, breaking)

πŸ’» Code

interface Data {
    rootValue: number;
    nested: {
        nestedValue: string;
    }
}

// Problem lies here
type Test<T> = {
    [K in keyof T]: T extends Record<string, unknown> ? Test<T[K]> : false;
};

// When using an interface, the mapped type for the nested field is incorrect
type WithInterface = Test<Data>;
type NestedInWithInterface = WithInterface['nested']; // false

// However when using a type directly it works as intended
type WithPlain = Test<{
    rootValue: number;
    nested: {
        nestedValue: string;
    }
}>;
type NestedInWithPlain = WithPlain['nested']; // { nestedVaue: string }


// Using a type instead of an interface also works as intended
type DataType = {
    rootValue: number;
    nested: {
        nestedValue: string;
    }
}

type WithType = Test<DataType>;
type NestedInWithType = WithType['nested']; // { nestedVaue: string }


// And using another mapped type that's just an identity of the input also works
type Identity<T> = {
    [K in keyof T]: T[K]
}

type WithInterfaceIdentity = Test<Identity<Data>>;
type NestedInWithInterfaceIdentity = WithInterfaceIdentity['nested']; // { nestedVaue: string }

πŸ™ Actual behavior

When using a recursive mapped conditional type (not sure if I named it correctly), typescript breaks when using an interface as the generic parameter, but works when using inline types, type aliases and a mapped type.

πŸ™‚ Expected behavior

Expected NestedInWithInterface to be { nestedVaue: string }, just like NestedInWithPlain, NestedInWithType, and NestedInWithInterfaceIdentity.

@ItsaMeTuni ItsaMeTuni changed the title Recursive mapped conditional types not working when using interfaces Recursive mapped conditional types not working when using interfaces (regression between 3.3.3 and 3.5.1) Sep 13, 2022
@whzx5byb
Copy link

See #50087 (comment)

@ItsaMeTuni
Copy link
Author

ItsaMeTuni commented Sep 13, 2022

See #50087 (comment)

Of course! It makes total sense, I can't believe I missed that and spent hours debugging this... Sorry about the trouble and thanks for the quick response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants