javascript - Hvordan skrive TypeScript-definisjon for is(constructor, instance)-metode


La oss si at jeg har en is-funksjon, i praksis fungerer den slik.

is(Array, []) // true
is(String, '') // true

Fordi det er en JavaScript-funksjon, må jeg lage en egen TypeScript-definisjon for den.

Foreløpig kan jeg bare implementere grensesnittet nedenfor,

is(ctor: any, val: any): boolean;

Men denne definisjonen er ikke god nok, for etter at jeg kjører if(is(Array, stuffA)) { ... } kan typen til stuffA ikke utledes av TypeScript-kompilatoren inne i if-blokken.

Hvordan kan jeg få typepåstanden til å fungere for is-funksjonen?

Svar #1

Signaturen bør se slik ut:

function is<T>(type: { new(): T }, obj: any): obj is T

Dette vil sikre at kompilatoren forstår riktig type, det vil si at denne funksjonen behandles som en typebeskytter.

Jeg har en slik funksjon også:

function is<T>(obj: any, type: { new(): T }): obj is T {
    if (Number.isNaN(type as any) && Number.isNaN(obj)) {
        return true;
    }

    let objType: string = typeof obj;
    let nameRegex: RegExp = /Arguments|Function|String|Number|Date|Array|Boolean|RegExp/;

    if (obj && objType === "object") {
        return obj instanceof type;
    }

    let typeName: RegExpMatchArray = type.toString().match(nameRegex);
    if (typeName) {
        return typeName[0].toLowerCase() === objType;
    }

    return false;
}

(kode i lekeplass)

Rediger

Når vi bruker denne funksjonen vil vi alltid sende inn en instans og deretter klassen.
Siden vi vil at funksjonen skal dekke alle typer, vil vi bruke generiske typer, hvor T er typen til den sendte instansen.

Hvis T er typen til instansen, er typen til klassen:

{ new(): T }

Det er den "TypeScript-måten" å beskrive et konstruktørobjekt (som også er en klasse).
Mer kan finnes her: Forskjellen mellom de statiske og instanssidene av klasser.

Relaterte artikler