【问题标题】:Generic type with specific key and value具有特定键和值的通用类型
【发布时间】:2020-06-28 21:01:10
【问题描述】:

我正在研究接受两个泛型类型参数的函数。其中之一是Object 类型,另一个是扩展keyof 传递对象类型的字符串。我需要以某种方式确定提供的Object 必须包含第二个参数中提供的键,并且它的值也应该是指定的类型。

我尝试过这样的事情:

const someFn = <
  T extends {[key: string]: number | null},
  K extends keyof T
>(data: T[], dataField: K) => {

  // expecting data values to be (number | null)[] for further purposes
  const dataValues = data.map(datum => datum[dataField]);

}

然而,上面的代码只有在传递的对象中的所有键都是number | null时才有效

type WorkingType = { value: number | null }
const workingArray = [{value: 1}, {value: null}]

someFn<WorkingType, "value">(workingArray, "value") // this works just fine

但是如果对象包含不同类型的字段我得到错误:

type FailingType = { value: number | null, sthElse: string }
const workingArray = [{value: 1, sthElse: ""}, {value: null, sthElse}]

//. Property 'sthElse' is incompatible with index signature.
//   Type 'string' is not assignable to type 'number | null'
someFn<FailingType, "value">(workingArray, "value") 

所以我需要做的是以某种方式提供信息,即只有作为K 提供的密钥需要是number | null 我尝试了类似的方法:

const someFn<
  T extends { [key: T]: number | null },
  K extends keyof T
>(data: T[], dataKey: K) => {/* ... */}

但这似乎是 TS 不允许的,我得到了An index signature parameter type must be either 'string' or 'number'。有没有可能达到我的目标的方法?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    我希望我明白你的意思,无论如何这对我有用:

        interface someFnI {
        <T,K extends keyof T>(data: T[], dataField: K);
    }
    
    
    
    const someFn = <
        T,
        K extends keyof T
    >(data: T[], dataField: K) => {
    
        // expecting data values to be (number | null)[] for further purposes
    const dataValues: T[K][] = data.map(datum => {
        return datum[dataField]});
        console.log(dataValues);
    
    }
    
    let myIdentity: someFnI = someFn;
    
    
    type NotFailingType = { value: number | null, sthElse: string }
    const workingArray = [
        { value: 1, sthElse: "" }, 
        { value: null, sthElse: null },
        //this will break as expected : uncomment below to check
        // { value: "notallowed", sthElse: null }
    ]
    
    //. Property 'sthElse' is incompatible with index signature.
    //   Type 'string' is not assignable to type 'number | null'
    myIdentity<NotFailingType, "value">(workingArray, "value")
    
    
    
    type WorkingType = { value: number | null }
    const workingArray2 = [{ value: 1 }, { value: null }]
    
    myIdentity<WorkingType, "value">(workingArray2, "value")
    

    【讨论】:

    • 您好,感谢您的回答。不幸的是。这个解决方案不起作用,因为打字稿在这里没有推断出 dataValues(number | null)[] 类型并在我尝试使用它时抛出错误。
    • 我编辑了我的答案,并明确了数据值的类型(泛型)。 const dataValues: T[K][] ,但我没有得到你得到错误的地方,使用你的问题中的数据我没有得到任何错误。实际上 datavalues 是 (number | null)[]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    相关资源
    最近更新 更多