typescript - 当 myRecord 已经输入为 Record 时如何使用 `keyof typeof myRecord`
问题描述
示例 1:
const myGroup = {
Alice: { age: 5 },
Bob: { age: 6 },
}
function getAge(name: keyof typeof myGroup) {
return myGroup[name].age;
}
getAge('Charlie'); // error: name must be 'Alice' | 'Bob'
↑ 这就是我想要的,但是,如果我输入所有内容,它将不再起作用:
示例 2
interface People {
age: number;
}
interface PeopleGroup {
[name:string]: People;
}
const myGroup: PeopleGroup = {
Alice: { age: 5 },
Bob: { age: 6 },
}
function getAge(name: keyof typeof myGroup) {
return myGroup[name].age;
}
getAge('Charlie'); // no error, name has type of string
我知道我可以使用enum
or来解决它union type
,但是在添加人员时需要编辑多个位置。在我的实际项目中,myGroup
是一个结构复杂的大型硬编码字典,我希望既享受硬编码时的类型检查,又享受查询时的类型检查。有干燥的方法吗?
解决方案
好的,问题是当您说某事时,Record<string, People>
任何字符串键都是正确的,并且类型myGroup
不会缩小到真正存在的键。为了在两个地方实现类型安全:
- 在字典创建级别以具有适当的界面
- 已将类型缩小到字典的确切键
我们需要引入值构造函数:
function makeGroup<T extends PeopleGroup>(input: T) {
return input;
}
// using
const myGroup = makeGroup({
Alice: { age: 5 },
Bob: { age: 6 },
});
它所做的是它需要与接口匹配的东西PeopleGroup
- 它是第一个类型安全元素,这意味着参数需要是PeopleGroup
并返回窄类型。第二个非常重要,使用泛型类型表示我们要推断参数的确切类型的 TS。作为输出的结果,我们有确切的参数类型。
完整代码:
interface People {
age: number;
}
interface PeopleGroup {
[name:string]: People;
}
// value constructor
function makeGroup<T extends PeopleGroup>(input: T) {
return input;
}
// correct creating of group - type safe for PeopleGroup
const myGroup = makeGroup({
Alice: { age: 5 },
Bob: { age: 6 },
});
const myGroupError = makeGroup({
Alice: { age: 5 },
Bob: { age: 'a' }, // error as it should be
});
function getAge(name: keyof typeof myGroup) {
return myGroup[name].age;
}
getAge('Alice') // ok !
getAge('Charlie'); // error as it should be
推荐阅读
- python - 如何在 str.format() 方法中使用变量?
- javascript - p5.js 网页编辑器。'未捕获的类型错误:无法读取未定义的属性'拆分'(:第 57 行)'
- java - 搜索时 JTable - 没有得到正确的 ID
- html - 如果找到关键字,如何获取行号及其文本
- javascript - 汇总未检测到 scss 文件的 @import 语法
- apache-kafka - Apache Kafka 和 JSON 模式
- python - python中的bcrypt在比较输入和存储的密码时返回false
- java - 这个接口代码是如何用Java编译的?
- sql-server - 这个 SQL Server ALTER TABLE 子句中的 FOR 关键字有什么作用?
- amazon-web-services - 跨帐户共享极光无服务器数据库集群的最佳方式是什么?