简体   繁体   English

"在 TypeScript 中推断接口属性类型"

[英]Infer interface property type in TypeScript

Say I have this interface and an object that contains that type:假设我有这个接口和一个包含该类型的对象:

interface IMyData {
    a: TypeA;
    b: TypeB;
    c: boolean;
    d: string;
}

const myObj: { data: IMyData } = {
    data: {
         a: someValueA,
         b: someValueB,
         c: true,
         d: "someValueD"
    }
}

You have to tell the typesystem the exact literal value of field . 您必须告诉类型系统field的确切字面值。 The easiest way to do that is to use a generic function like this: 最简单的方法是使用如下通用函数:

interface IMyData {
    c: boolean;
    d: string;
}

const myObj: { data: IMyData } = {
    data: {
         c: true,
         d: "someValueD"
    }
}

function getField<T extends keyof IMyData>(obj: { data: IMyData }, field: T){
    return obj.data[field];
}

const myFieldStr = getField(myObj, "c"); // should infer type boolean
const myFieldBool = getField(myObj, "d"); // should infer type string

Or in the simplest general case: 或在最简单的一般情况下:

function pluck<T, K extends keyof T>(obj : T, key : K) {
    return obj[key];
}

const foo = pluck({ bar: "asd", baz: 5 }, "bar"); // infers string

A possible solution to the second (more complex) scenario would be to define a new type which will extract the type from the generic:第二种(更复杂)场景的可能解决方案是定义一个新类型,该类型将从泛型中提取类型:

type GenericOf<S> = S extends IMyValue<infer T> ? T : never;

Now you "plug-in" that type your function:现在您“插入”键入您的函数:


function getValue<T extends keyof IMyData2>(field: T, data: IMyData2) {
    // old solution: return data[field] ? data[field]!.value : undefined;
    return data[field]?.value as GenericOf<IMyData2[T]>;
}

This will result the return values of the function to be correctly typed:这将导致正确键入函数的返回值:

const testValue1 = getValue('a', testData); // string | undefined
const testValue2 = getValue('b', testData); // number | undefined
const testValue3 = getValue('c', testData); // boolean | undefined
const testValue4 = getValue('d', testData); // string | undefined

This is not the most elegant solution but it works!这不是最优雅的解决方案,但它有效!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM