Typescript-funktions returtype baseret på klasseegenskab


Jeg har følgende klasse og funktion:

class Test {
  prop: string;
  otherProp: number;

  constructor() {
    const result = doSomething<Test>('prop');
  }
}

function doSomething<T>(propName: keyof T): ???? {
  // ,,,
}

Der er en måde med TypeScript, hvor jeg kan returnere fra funktionen den samme type som den egenskab, som funktionen får. I eksemplet ovenfor burde returtypen være string. Hvis jeg kalder den med otherProp, burde returtypen være number.

Svar #1

Du har brug for en ekstra typeparameter for at fange den faktiske type af den nøgle, der er sendt ind (lad os kalde den K). Du kan derefter bruge K til at indeksere i T (dvs. bruge en typparallel forespørgsel)

class Test {
    prop: string;
    otherProp: number;

    constructor() {
        const result = doSomething(this, 'prop');
    }
}

function doSomething<T, K extends keyof T>(target: T, propName: keyof T): T[K] {
    return this[propName];
} 

Jeg ændrede eksemplet ovenfor for at sende en parameter med typen T for at udlede både K og T fra parametrene. Typescript understøtter ikke delvis typeudledning, så vi kan ikke specificere T og få K udledt. Så hvis vi ikke har en parameter af typen T, ville vi skulle skrive:

class Test {
    prop: string;
    otherProp: number;

    constructor() {
        const result = doSomething<Test, 'prop'>('prop');
    }
}

function doSomething<T, K extends keyof T>(propName: keyof T): T[K] {
    return this[propName];
} 

En bedre version er at bruge en funktion, der returnerer en funktion, og have T fastlagt i det første kald og K udledt i det andet:

class Test {
    prop: string;
    otherProp: number;

    constructor() {
        const result = doSomething<Test>()('prop');
    }
}

function doSomething<T>() {
    return function <K extends keyof T>(propName: keyof T): T[K] {
        return this[propName];
    }
}

Relaterede artikler