Skip to content

Inlining definition of NonNullable<T> results in different behavior #23046

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
farnoy opened this issue Mar 31, 2018 · 2 comments
Closed

Inlining definition of NonNullable<T> results in different behavior #23046

farnoy opened this issue Mar 31, 2018 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@farnoy
Copy link

farnoy commented Mar 31, 2018

Apologies if this was submitted already, I could not find anything similar by searching.

TypeScript Version: 2.8.1

Search Terms: Existential types, undefined, Exclude, Required, NonNullable, in keyof

Code

type OnlyPresentV1<T> = {
    [P in keyof T]: NonNullable<T[P]>
};

// should pass, and it does
const Test_1: OnlyPresentV1<{test: string}> = {test: "asd"};
// should fail, and it does
const Test_2: OnlyPresentV1<{test: string}> = {test: undefined};
// should pass, and it does
const Test_3: OnlyPresentV1<{test: string | undefined}> = {test: "asd"};
// should fail, and it does
const Test_4: OnlyPresentV1<{test: string | undefined}> = {test: undefined};

type OnlyPresentV2<T> = {
    [P in keyof T]: T[P] extends null | undefined ? never : T[P] 
};

// should pass, and it does
const Test_5: OnlyPresentV2<{test: string}> = {test: "asd"};
// should fail, and it does
const Test_6: OnlyPresentV2<{test: string}> = {test: undefined};
// should pass, and it does
const Test_7: OnlyPresentV2<{test: string | undefined}> = {test: "asd"};
// should fail, but it doesn't!
const Test_8: OnlyPresentV2<{test: string | undefined}> = {test: undefined};

Expected behavior:
I noted down what my expectations are above each case.
I expected that inlining the definition of NonNullable would be the same as using the type.

Actual behavior:
Behavior is different, but definitions are essentially the same?

Playground Link: https://goo.gl/fWzwzA (shortend it because it was really long) Enabled all strictness checks I could

Related Issues: Could not find any

@jack-williams
Copy link
Collaborator

The semantics of conditional types are not preserved by inlining. NonNullable is distributive, your inline version is not.

Related: #23022

@farnoy
Copy link
Author

farnoy commented Mar 31, 2018

That's tricky but I think I understand. Thanks for the quick response.

@farnoy farnoy closed this as completed Mar 31, 2018
@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 2, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 25, 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

3 participants