typeguards - Typescript Type Guards og fet pil-funksjon


Bør ikke dette kompileres riktig? Jeg får en feil "Egenskapen 'hello' eksisterer ikke på typen 'object'." på den uthevede linjen.

Jeg kan få tilgang til g.hello utenfor fat arrow-funksjonen uten problemer.

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    () => {
        g.hello();    ////// ERROR HERE /////
    };
}

Svar #1

Innstrammingen som en typebeskyttelse gjør på en variabel (eller noe annet) vil ikke krysse funksjonsgrenser. Dette er en designbegrensning.

En måte å omgå dette problemet på er å tilordne g til en ny variabel, som vil få sin type utledet basert på innsnevringen. Å få tilgang til den nye variabelen i pilfunksjonen vil fungere som forventet:

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

let g : object;

if (g instanceof Test) {
    const gTest = g;
    () => {
        gTest.hello();
    };
}

En annen måte å omgå dette problemet på hvis g ikke endres, er å erklære g med const. Dette vil la kompilatoren bevare innsnevringen:

let g : object;

if (g instanceof Test) {
    const gTest = g;
    () => {
        gTest.hello();
    };
}

Lekeromlenke

Svar #2

let + pilfunksjon

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare let g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // error
    };
}

g er en Test når funksjonen er definert, men g kanskje ikke er Test når funksjonen kjøres.

const + pilfunksjon

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    () => {
        g.hello(); // ok
    };
}

g er uforanderlig, g er alltid en Test etter at funksjonen er definert.

const + vanlig funksjon

class Test {
    constructor() {
    }
    hello() : string {
        return "Hello";
    }
}

declare const g : object;

if (g instanceof Test) {
    function f() {
        g.hello(); // error
    };
}

Innen underliggende implementering er vanlig funksjon f definert av ES5 var, i stedet for ES6 let. Variabelhoisting flytter deklarasjonen av f, når g kanskje ikke er en Test.

Relaterte artikler