oop - typescript grensesnittinitialisering


Mitt nivå i TypeScript er 'ABSOLUTT NYBEGYNNER', men jeg har god bakgrunn i OOP. Jeg bygger en med TypeScript som refererer til et eksternt t.ds-bibliotek som inneholder følgende grensesnitt:

interface ISimpleObject {
    foo: string;
    bar?: any;
}

Nå, hvis jeg vil kalle en metode som har en IRequestConfig-parameter, hvordan lager jeg en? Jeg kan se forskjellige alternativer:

  1. Lag en enkel implementasjon av ISimpleObject. Jeg liker ikke denne tilnærmingen fordi det ser ut som standardkode for meg
  2. ikke initialiser objektet (jeg frykter dette kan ødelegge noe...):

    var x :IsimpleObject; x.bar='xxx'; callMethod(x);

  3. Kast en pojo:

    var x :IsimpleObject = <IsimpleObject>{foo: 'yyy', bar:'xxx'};

    Jeg liker heller ikke denne tilnærmingen fordi den ikke håndhever typesikkerhet...

Jeg antar at dette er et ganske trivielt spørsmål, og at jeg går glipp av noe trivielt om TypeScript.

Svar #1

Typescript2:

const simpleObject = {} as ISimpleObject;

Svar #2

Hvis du har et grensesnitt som:

interface ISimpleObject {
    foo: string;
    bar?: any;
}

Dette grensesnittet brukes bare under kompilering og for kodeforslag/intellisense. Grensesnitt brukes for å gi en streng og typesikker måte å bruke et objekt med en definert signatur på en konsistent måte.

Hvis du har en funksjon som bruker interface definert ovenfor:

function start(config: ISimpleObject):void {

}

TypeScript-kompileringen vil mislykkes hvis et objekt ikke har nøyaktig signatur som ISimpleObject-grensesnittet.

Det finnes flere gyldige teknikker for å kalle funksjonen start:

// matches the interface as there is a foo property
start({foo: 'hello'});

// Type assertion -- intellisense will "know" that this is an ISimpleObject
// but it's not necessary as shown above to assert the type
var x = <ISimpleObject> { foo: 'hello' }; 
start(x);

// the type was inferred by declaration of variable type
var x : ISimpleObject = { foo: 'hello' };  
start(x);

// the signature matches ... intellisense won't treat the variable x
// as anything but an object with a property of foo. 
var x = { foo: 'hello' };
start(x);    

// and a class option:
class Simple implements ISimpleObject {
    constructor (public foo: string, public bar?: any) {
       // automatically creates properties for foo and bar
    }
}
start(new Simple("hello"));

Hver gang signaturen ikke stemmer, vil kompileringen mislykkes:

// compile fail
var bad = { foobar: 'bad' };
start( bad );

// compile fail
var bad: ISimpleObject = { foobar: 'bad' };

// and so on.

Det finnes ingen "riktig" måte å gjøre det på. Det er et spørsmål om stilvalg. Hvis det var et objekt som ble konstruert (i stedet for bare å bli sendt direkte som en parameter), ville jeg normalt erklært typen:

var config: ISimpleObject = { foo: 'hello' };

På den måten vil kodefullføring/IntelliSense fungere hvor som helst jeg brukte config-variabelen:

config.bar = { extra: '2014' };

Det finnes ingen "casting" i TypeScript. Det kalles en typepåstand og bør ikke være nødvendig i de beskrevne tilfellene her (jeg inkluderte et eksempel ovenfor hvor det kunne brukes). Det er ikke nødvendig å erklære variabeltypen og deretter bruke en påstand i dette tilfellet (da typen allerede var kjent).

Relaterte artikler