【问题标题】:How to infer a typed array from a dynamic key array in typescript?如何从打字稿中的动态键数组推断类型化数组?
【发布时间】:2018-11-19 09:09:36
【问题描述】:

我希望键入一个通用对象,并让该对象的属性返回一个类型化数组。从对象获取单一类型属性的能力已记录并有效,但是我无法让它与数组一起使用。似乎是“联合类型”。

// 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

【问题讨论】:

    标签: typescript


    【解决方案1】:

    问题是keys 可以是T 的任何键,所以当你在getProperties 中调用getProperty 时,结果将是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
    

    【讨论】:

    • 谢谢!这解决了数组问题;有没有办法解决地图界面的类似问题? const getProperties = (map: { [key: string]: K }) => { [key: string]: T[K] };
    • 这个问题在stackoverflow.com/questions/50822693/…得到了回答
    猜你喜欢
    • 2020-04-02
    • 2021-09-16
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2020-03-22
    • 1970-01-01
    • 2020-01-21
    相关资源
    最近更新 更多