如何从typescript中的动态键数组推断出一个类型化的数组?

时间:2018-06-09 14:31:53

标签: typescript

我希望键入一个通用对象,并使该对象的属性返回一个类型化数组。从对象获取单一类型属性的能力被记录并且有效,但是我无法使用数组来处理它。似乎是'联合类型'。

// from the documentation 
// @ http://www.typescriptlang.org/docs/handbook/advanced-types.html
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
    return o[name];
}

const a = getProperty(person, 'age');
// a: number
const n = getProperty(person, 'name');
// n: string

const getProperties = <T>(obj: T, keys: Array<keyof T>) => keys.map((arg) => getProperty(obj, arg));

const [a2, n2] = getProperties(person, ['name', 'age']);
// result:
// a2: string | number
// n2: string | number

// what i want:
// a2: string
// n2: number

1 个答案:

答案 0 :(得分:0)

问题是keys可以是T的任意键,因此当您在getProperty内拨打getProperties时,结果将为T[keyof T],意味着任何值T。对于getProperty(person, 'age')它可行,因为name将被推断为字符串文字类型'age',因此结果将是T['age'] number

要完成您想要的任务,我们需要为将要传递的每个键分别使用一个通用参数。我们不能支持任意数量的键,但是,使用重载,我们可以支持一定数量的键,这对于大多数情况来说已经足够好了(我为多达3个键增加了重载,你可以轻松添加更多) :

const person = {
    age: 1,
    name: ""
}
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
    return o[name];
}


function getProperties<T, K extends keyof T, K2 extends keyof T, K3 extends keyof T>(obj: T, keys: [K, K2, K3]): [T[K], T[K2], T[K3]]
function getProperties<T, K extends keyof T, K2 extends keyof T>(obj: T, keys: [K, K2]): [T[K], T[K2]]
function getProperties<T, K extends keyof T>(obj: T, keys: [K]): [T[K]]
function getProperties<T>(obj: T, keys: Array<keyof T>) {
    return keys.map((arg) => getProperty(obj, arg));
} 

const [a2, n2] = getProperties(person, ['name', 'age']); // a2: string, n2: number