typescript - 类型联合不检查多余的属性
问题描述
让我们假设一个对象具有属性A
和B
或C
,例如:
const temp = {
A: 1,
B: 2,
}
或者
const temp = {
C: 3,
}
直观地,我将这种类型视为:
type T = {A: number, B: number} | {C: number};
const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};
// Should complain but it does not
const invalid: T = {A: 1, B: 2, C: 3};
// Also should complain
const alsoInvalid: T = {A:1, C: 3};
但是 TS 将此类类型视为{A?: number, B?: number, C?: number}
并且基本上使字段可选但我希望 TS 在我添加属性时|
抱怨类型不一致C
A
B
如何归档所需的类型?
解决方案
这是工会如何与过多的财产检查相结合的一个怪癖。除了多余的属性检查之外,{A:1, C: 3}
实际上是兼容的:{C: number}
const o = {A:1, C: 3};
const ok: {C: number} = o; // No direct literal assignment, no excess property checks
const nok: {C: number} = { A:1, C: 3}; // Excess property checks kick in
多余的属性检查的怪癖是,对于联合,它允许来自任何联合成分的任何属性出现在分配的对象文字中。
如果联合组成部分彼此不兼容,您可能会收到错误消息:
type T = {A: number, B: number} | {C: number, A?: undefined, B?: undefined };
const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};
// Error
const invalid: T = {A: 1, B: 2, C: 3};
//Error
const alsoInvalid: T = {A:1, C: 3};
如果工会有很多成员,您也可以使用StrictUnion
from here
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
type T = StrictUnion<{A: number, B: number} | {C: number }>;
const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};
// Error
const invalid: T = {A: 1, B: 2, C: 3};
//Error
const alsoInvalid: T = {A:1, C: 3};
推荐阅读
- angular - Tab 键在模式对话框内的输入中不起作用(Angular 应用程序/PrimeNG)
- java - 测试休眠 OneToMany 映射
- .htaccess - 使用 .htaccess 将 root/dir 重定向到 root/new/dir
- awk - 表示人的姓名首字母和skype用户,其中skype用户以字母开头,以数字结尾;
- c# - 我的程序正在使用 Office 集成并针对没有 MS Office、C# 的窗口
- python - 在其他程序正在用 python 写入文件时读取文件
- vim - 有没有办法使用'。键而不是';' 在vim中重复内联搜索的键('f'键)
- sql - 在Oracle PlSql中的参数中添加不带逗号的字符串
- javascript - 从触发器内创建云存储桶中的文件
- angular - 使用 Angular HTTP 拦截器管理多个同时异步服务调用的加载器/微调器