Skicka typ dynamiskt till funktion i TypeScript


Jag har två gränssnitt som detta

interface CatStateProps {
    data: CatState[],
    food: number[]
}

interface DogStateProps {
    data: DogState[],
    food: string[]
}

som jag använder i en typ-definition

type AnimlState= {
    cat?: CatStateProps ,
    dog?: DogStateProps,
};

Och med det type skapar jag ett objekt

const catsAndDogs: AnimlState = {
    cat: {data: [...], food: [...]}
    dog: {data: [...], food: [...]}
};

Nu får jag åtkomst till dog

let {dog} = catsAndDogs // dog has the types CatStateProps | DogStateProps
if(dog) {
    let {data} = dog // data has the types CatState[] | DogState[]
    foo(data);
}

Men så snart jag skickar data som ett funktionsargument till foo(), blir det av typen any i funktionen foo().

const foo = (data: ?) => {...}

Nu, hur skulle jag skicka typen av data till funktionen foo(), inte göra det så här

const foo = (data: CatState[] | DogState[]) => {...}

Jag vill skicka typen av data i foo() dynamiskt, så att när jag ändrar AnimlState behöver jag inte lägga till en annan typ till foo().

Svar #1

Om jag har förstått frågan rätt vill du att parametern för din funktion ska baseras på AnimlState

Du kan uppnå det på detta sätt:

const foo = (data: Required<AnimlState>[keyof AnimlState]['data']) => { }
             // ^? (parameter) data: CatState[] | DogState[]

TS Lekplats


Required används för att utesluta undefined som möjlig värde från AnimlState[keyof AnimlState], vilket också skulle kunna uppnås med

(data: NonNullable<AnimlState[keyof AnimlState]>['data']) => {}