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

Index key accessed nullable index type is not narrowed from nullable #12636

Closed
tinganho opened this issue Dec 3, 2016 · 5 comments
Closed

Index key accessed nullable index type is not narrowed from nullable #12636

tinganho opened this issue Dec 3, 2016 · 5 comments
Assignees
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed Suggestion An idea for TypeScript

Comments

@tinganho
Copy link
Contributor

tinganho commented Dec 3, 2016

interface S {
    hello: any;
}

interface R {
    [i: string]: S | undefined;
}

function f<K extends keyof R>(p: K) {
    let r: R = {};
    if (r[p]) {
        r[p].hello // Error: hello does not exists on type R[K]
    }
}

Removing the type undefined from S | undefined fixes the error and also the if check is no longer required.

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Dec 3, 2016

I think this might be a duplicate of #10530. Could you post your example on #10565 just so we can add a test case?

@DanielRosenwasser DanielRosenwasser added Duplicate An existing issue was already created and removed Duplicate An existing issue was already created labels Dec 3, 2016
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Dec 3, 2016

This is actually a little iffy - despite how we'd like to think about it, there's not anything that really ties keyof R to R. In the end, keyof R is really just equivalent to string.

@tinganho
Copy link
Contributor Author

tinganho commented Dec 8, 2016

@DanielRosenwasser though it does ties to R if you remove undefined?

interface S {
    hello: any;
}

interface R {
    [i: string]: S;
}

function f<K extends keyof R>(p: K) {
    let r: R = {};
    if (r[p]) {
        r[p].hello // No error
    }
}

@mhegazy mhegazy added the Bug A bug in TypeScript label Dec 8, 2016
@mhegazy mhegazy added this to the TypeScript 2.2 milestone Dec 8, 2016
@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Jan 10, 2017
@ahejlsberg
Copy link
Member

Aside from not supporting narrowing with element access expressions (which is tracked by #10530), we would have to introduce a new type operator that records the fact that a truthy check has been performed on some generic type. For example, given a T! operator that represents a truthy check on T, within the if block, r[p] would have type R[K]!. Then, when we obtain the apparent type of R[K]! in the property access r[p].hello we would know to remove undefined from the type.

However, introducing new type operators is not a trivial matter, and I'm not sure it is worth the effort in this particular scenario.

@ahejlsberg ahejlsberg added Suggestion An idea for TypeScript and removed Bug A bug in TypeScript labels Jan 10, 2017
@mhegazy mhegazy removed this from the TypeScript 2.2 milestone Jan 11, 2017
@mhegazy
Copy link
Contributor

mhegazy commented Apr 24, 2017

Closing in favor of #14366 and #10530.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants