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

Type guards for type variables #31133

Closed
marsiancba opened this issue Apr 27, 2019 · 2 comments
Closed

Type guards for type variables #31133

marsiancba opened this issue Apr 27, 2019 · 2 comments
Labels
Duplicate An existing issue was already created

Comments

@marsiancba
Copy link

Currently (3.4) type guards do not work when variable is declared using type variable. Ideally type guard should be applied not only to variable, but also to type variable. More details in sample code below:

interface RecordTypes {
    cat: { name: string };
    dog: { name: string };
    person: { firstname: string, lastname: string };
}
type Kind = keyof RecordTypes; // "cat" | "dog" | "person" 

function logAnimal(kind: "cat" | "dog") { /* */ }

function logAny(kind: Kind) {
    if (kind == "cat" || kind == "dog") {
        // type guard is applied here, so typescript knows
        // that typeof kind == "cat" | "dog" in this block
        // and we can call logAnimal function without error

        logAnimal(kind); // OK
    }
    /* */
}

// But type guards do not work if we use type variables

function getName<K extends Kind>(kind: K, record: RecordTypes[K]) {
    if (kind == "cat" || kind == "dog") {
        // type guard is not applied here, so typescript does not know
        // that typeof kind == "cat" | "dog" in this block
        // and we get error when calling logAnimal function

        logAnimal(kind); // ERROR!!!

        // Correct behaviour should be to apply type guard not only
        // to variable kind, but also to type variable K, so in this block:
        // K extends "cat" | "dog"
        // and then typescript will also know that
        // typeof record == RecordTypes["cat" | "dog"]
        // and next line will compile withot error

        return record.name; // ERROR!!!
    }
    if (kind == "person") {
        return record.firstname + ' ' + record.lastname; // ERROR!!!

        // ^^^ This is actual problem we often ecounter in our project that
        // for this kind of code we have to add typecasts or create typecasted 
        // variables like:
        // const person = record as RecordTypes["person"];
    }
}

Search Terms

type guards type variables

@jack-williams
Copy link
Collaborator

Duplicate of #13995

@weswigham weswigham added the Duplicate An existing issue was already created label May 8, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants