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

strictNullChecks blocks safe typeof capture #16108

Closed
dylanscott opened this issue May 26, 2017 · 9 comments
Closed

strictNullChecks blocks safe typeof capture #16108

dylanscott opened this issue May 26, 2017 · 9 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@dylanscott
Copy link

Sorry if this is a dupe - I tried searching but github's search isn't great.

TypeScript Version: 2.3.1

Code

interface Nested {
    child: {
        prop: string
    }
}

declare function maybeGetNestedValue(): Nested | null

const nested = maybeGetNestedValue()

const child: typeof nested.child = {
    prop: 'value'
}

TypeScript Playground link
Note: You need to manually enable strictNullChecks under the options for this link. If I enable it and try to share it says the text buffer is too big to share.

Expected behavior: I would expect to be able to use typeof to capture the type of this nested field, since as you can see in the emitted code in the TypeScript Playground link, there is no dereference of the nested field emitted, so the code should always be safe.

Actual behavior: The strictNullChecks flag raises an error because the nested field may be null.

@dylanscott
Copy link
Author

Also note: It appears you cannot use the non-null assertion operator to appease the compiler here. typeof nested!.child doesn't appear to even be syntactically valid.

@aluanhaddad
Copy link
Contributor

That error message is indeed strange in type position.

What type would you expect the child variable to have?
It cannot be

{
    prop: string
}

@dylanscott
Copy link
Author

dylanscott commented May 26, 2017

Ah, I suppose it can't. I'm trying to capture the type { prop: string } but you're right that I was thinking about it wrong. typeof nested.child isn't well-defined (or maybe it is? maybe { prop: string } | never). In this case I guess you could just do Nested['child'], but that doesn't work if you have further layers of nesting with potentially null fields.

@aluanhaddad
Copy link
Contributor

The simplest fix is to create an extra local which is obviously not ideal or, as you need to test nested itself before use, you could just test it earlier

declare function maybeGetNestedValue(): Nested | null;

const nested = maybeGetNestedValue();
const notNullNested = nested!;
const child: typeof notNullNested.child = {
    prop: 'value'
};

@ghost
Copy link

ghost commented May 27, 2017

You can also use Nested["child"].

@aluanhaddad
Copy link
Contributor

@andy-ms right, thank you! I keep forgetting about that syntax. It's definitely the way to go here.

@RyanCavanaugh RyanCavanaugh added In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels May 30, 2017
@RyanCavanaugh
Copy link
Member

Feels like property access in typeof expressions should implicitly be getting x!.y. Unclear what value there is warning someone about a possibly-null x in that case

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Committed The team has roadmapped this issue and removed In Discussion Not yet reached consensus labels Jan 30, 2018
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 2.8 milestone Jan 30, 2018
@RyanCavanaugh RyanCavanaugh added the Good First Issue Well scoped, documented and has the green light label Jan 30, 2018
@RyanCavanaugh
Copy link
Member

Easy PR if anyone wants to grab this

@mhegazy
Copy link
Contributor

mhegazy commented Mar 9, 2018

Discussed this again in #22445. Conclusion, with NonNullable available now with conditional types, the original scenario should be unblocked, no reason to add new rules.

So the sample in the OP would look like:

const child: NonNullable<typeof nested>["child"] = {
    prop: 'value'
}

@mhegazy mhegazy closed this as completed Mar 9, 2018
@mhegazy mhegazy added Declined The issue was declined as something which matches the TypeScript vision and removed Committed The team has roadmapped this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this labels Mar 9, 2018
@mhegazy mhegazy removed this from the TypeScript 2.8 milestone Mar 9, 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
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants