typescript - 基于参数的显式返回类型
问题描述
给定一个函数,它接受一个对象数组,并返回一个对象,其键都对应于参数中每个对象的属性......似乎应该有一种方法来获得更明确的返回类型。
功能-
function objectFromArray(arr: { key: string }[]) {
let obj: {[k: string]: true} = {};
for (let {key} of arr) {
obj[key] = true;
}
return obj;
}
如果我运行以下
let myArray = [{key: 'a'}, {key: 'b'}, {key: 'c'}];
let myObj = objectFromArray(myArray);
那么类型myObj
是
let myObj: {
[k: string]: true;
}
但我觉得存在足够的信息,以便打字稿推断出的类型myObj
实际上是
let myObj: {
a: true;
b: true;
c: true;
}
我的问题是在函数中需要做什么objectFromArray
才能根据参数派生显式返回类型。为了清楚起见,我不担心返回类型的值,只担心获取显式键。
解决方案
如果你想让它工作,你需要objectFromArray()
成为元素属性中字符串文字值类型的通用函数:K
key
arr
function objectFromArray<K extends string>(arr: readonly { key: K }[]) {
let obj = {} as { [P in K]: true }; // have to assert this because it's not true yet
for (let { key } of arr) {
obj[key] = true;
}
return obj;
}
readonly
inreadonly { key: K }[]
只是意味着我们并不特别要求传入的数组是可变的。这为输入提供了更多的余地,我们稍后会需要。
返回类型{ [P in K]: true }
是一个映射类型,它true
为K
. (您也可以使用Record
实用程序类型来提供等价的Record<K, true>
)。由于{}
is 不是此类型的有效值,因此您需要一个类型断言来告诉编译器将obj
其视为 type { [P in K]: true }
。
然后,当您创建时myArray
,编译器的默认行为是将其类型扩展为Array<{key: string}>
,完全忘记字符串文字类型"a"
,"b"
和"c"
。为了防止这种情况,您可以使用const
断言:
let myArray = [{ key: 'a' }, { key: 'b' }, { key: 'c' }] as const;
/* let myArray: readonly [{
readonly key: "a";
}, {
readonly key: "b";
}, {
readonly key: "c";
}] */
注意const
断言是如何创建myArray
一个readonly
数组的,这就是为什么放宽函数的输入类型是有用的。既然编译器已经足够了解 了myArray
,让我们调用objectFromArray()
:
let myObj = objectFromArray(myArray);
/* let myObj: {
a: true;
b: true;
c: true;
} */
成功! myObj
根据需要,已知具有a
、b
和c
类型的属性true
。
推荐阅读
- node.js - 基于允许和不能导入哪些模块的 TypeScript lint 文件和文件夹
- c# - 如何从同一 Azure AD 中的另一个 Web 应用程序访问 Web api?
- python - 使用切片和列表索引数据框
- c - 在 Ubuntu 18.04.1 上与 gcc-6 的覆盖兼容性?
- r - r 使用随机换行符格式化 csv 并导出
- node.js - 不从身份验证代码返回刷新令牌
- jquery - 通过 jQuery 重新加载脚本
- html - 如何强制固定导航栏具有页面的全宽而不是视口?
- jquery - jQuery toggleClass 显示面板。通过单击身体或屏幕上的任何位置关闭
- c - 根据字符串输入返回 sizeof