【问题标题】:Typescript parameters - a generic array of objects and array of object's keys (partial)打字稿参数 - 对象的通用数组和对象键的数组(部分)
【发布时间】:2019-05-28 20:57:14
【问题描述】:

我想要一个方法来接受一个对象数组和一些对象键的数组。该方法将返回一个对象值数组,但仅返回选定键的数组。

数据:

[
  {"firstName": "Jane", "lastName": "Doe"},
  {"firstName": "John", "lastName": "Doe"}
]

字段:

["firstName"]

结果:

[["Jane"], ["John"]]

现在我有一个函数可以提供所需的结果,但我不确定如何更好地处理这些类型。

mapToCsvData: (data: { [key: string]: any }[], fields: string[]) => {
  return data.map((item: any) => {
    return fields.map(field => item[field]);
  });
}

我尝试了下一个 sn-p 的一些变体,但出现错误。

mapToCsvData: <T extends object>(data: T[], fields: keyof T[]) => {
Property 'map' does not exist on type 'number'.

【问题讨论】:

    标签: arrays typescript typescript-generics keyof


    【解决方案1】:

    您将需要一个额外的类型参数来捕获实际传入的键元组。您可以将这个元组映射到T 中的相应属性类型。一切都很顺利:

    type MapKeyTupleToProps<T, P extends [keyof T] | Array<keyof T>> = {
        [K in keyof P]: P[K] extends keyof T ? T[P[K]] : never
    }
    const m = {
        mapToCsvData: <T, P extends [keyof T] | Array<keyof T>>(data: T[], fields: P): MapKeyTupleToProps<T, P> => {
            return data.map((item: any) => {
                return fields.map(field => item[field]);
            }) as any;
        }
    }
    
    const data = [
        {"firstName": "Jane", "lastName": "Doe", age: 0},
        {"firstName": "John", "lastName": "Doe", age: 0}
    ]
    
    let r = m.mapToCsvData(data, ["firstName", "lastName"]) // [string, string]
    let r2 = m.mapToCsvData(data, ["firstName", "age"]) //[string, number]
    

    【讨论】:

    • 谢谢。这真的很奇怪,但是当我将 MapKeyTupleToProps 移动到带有类型的主文件时,MapKeyTupleToProps 中的 P 亮起并显示错误“类型'[keyof T]' 不可分配给类型'flat'。”
    • @CrossTheDev 不确定为什么会发生这种情况.. 它应该可以工作.. 我相信 3.1 支持这种类型的映射元组。
    • 我目前使用的是 3.4.1,所以这应该不是问题。
    • 我发现了 t "P" 错误信息背后的问题。结果我的 linter 更喜欢 [] 而不是 Array,所以我将“Array>”更改为“keyof T[]”,但正确的变体是“(keyof T)[]”。我的错。
    • @CrossTheDev 是的.. 我更喜欢Array 如果项目类型不仅仅是一个单词,它更容易阅读。对于(keyof T)[],您需要输入(),您很容易错过最后的[]。我相信 lint 规则是可配置的
    猜你喜欢
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2021-02-24
    • 1970-01-01
    • 2020-05-16
    • 2018-06-26
    相关资源
    最近更新 更多