具有特定键和值的通用类型
Posted
技术标签:
【中文标题】具有特定键和值的通用类型【英文标题】: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'
。有没有可能达到我的目标的方法?
【问题讨论】:
【参考方案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)[]以上是关于具有特定键和值的通用类型的主要内容,如果未能解决你的问题,请参考以下文章
使用 Swift 将具有相同类型的字典分组到具有完整键和值的数组中