javascript - Node.js med TypeScript: kalle Node.js-funksjon i stedet for standard


vær så snill å hjelpe meg med følgende problem. Jeg laget en standard node.js-app med express ved å bruke Visual Studio nodejs-verktøy, og nå prøver jeg å kalle setTimeout-funksjonen som er deklarert i node.d.ts. Koden ser slik ut:

var timer: NodeTimer;
timer = setTimeout(somecallback, 1000);

Men koden kompilerer ikke og sier 'Kan ikke konvertere 'Number' til 'NodeTimer''

Som jeg forstår det, er problemet at den bruker standard setTimeout-funksjon i stedet for å bruke den fra node.d.ts.

Jeg prøvde å spesifisere referansen til node.d.ts med \\\<reference>-taggen - dette hjelper ikke. Hvordan kan jeg tydelig angi at jeg vil bruke setTimeout fra node.d.ts?

Svar #1

Jeg mistenker at dette ble ødelagt av en endring introdusert i TS 0.9.5, som er beskrevet i endringsloggen som:

Overbelastningsløsningsregler forenklet

Beskrivelse: Overbelastningsoppløsning følger nå en mye enklere algoritme. Når flere overbelastninger passer for et gitt kall, velger vi den første som passer i stedet for å prøve å finne den "beste passformen".

Dette betyr at kode med overbelastninger nå bør sorteres manuelt fra den mest spesifikke/strammeste overbelastningen til den løseste.

De to overbelastningene som er tilgjengelige, er følgende:

// in lib.d.ts
declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number;

// in node.d.ts
declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeTimer;

Klart vil den første overbelastningen alltid matche alt den andre kan matche, så den vil alltid bli foretrukket så lenge den er den første som vurderes.

I tilfelle der det finnes to .d.ts-filer, slik det er her, definerer rekkefølgen på filene den relative rekkefølgen på overbelastningene fra dem. Normalt kommer lib.d.ts alltid først, så den får prioritet. Men hvis du refererer til den manuelt, og sørger for at referansen kommer etter node.d.ts, vil den sistnevnte få prioritet, og du vil ende opp med riktig overbelastning.

Å gjøre dette fra kommandolinjen er enkelt - spesifiser bare .d.ts-filer eksplisitt i ønsket rekkefølge. For et VS-prosjekt kan du gjøre det samme med _references.ts, slik:

/// <reference path="Scripts/typings/node/node.d.ts" />
/// <reference path="C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\lib.d.ts" />

For å unngå å hardkode den absolutte banen slik, kan det hende du vil lage en lokal kopi av lib.d.ts i prosjektet ditt i Scripts/typings/node, sammen med node.d.ts.

Du vil kanskje også delta i diskusjonstråden om denne endringen på TypeScript-foraene, og dele din erfaring med TS-teamet.

Svar #2

Den enkleste tvungne løsningen :

var timer: NodeTimer;
timer = <any>setTimeout(somecallback, 1000);

Bare for moro skyld

Jeg laget et lite eksempel basert på de nåværende node-definisjonene (https://github.com/borisyankov/DefinitelyTyped/blob/master/node/node.d.ts#L22), og det fungerer bra i TypeScript-lekeplassen

interface NodeTimer{
    ref() : void;
    unref() : void;
}
declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeTimer;

var timer: NodeTimer;
timer = setTimeout(()=>{}, 1000);

Jeg vet ikke hvorfor du får en konflikt når jeg ikke gjør det. Forresten, den konfliktende setTimeout er definert i lib.d.ts, men den er også inkludert i TypeScript-lekeplassen og forårsaker ikke noe problem.

Relaterte artikler