typescript - TypeScript - 数组的约束
问题描述
我有以下(示例)数组:
[
'test-string',
foo => ({ foo }),
'other-string',
bar => ({ bar })
]
使用(示例)界面
interface MyValues { foo: string; bar: string; }
期望这种数组类型的函数必须保证所有函数的结果统一实现完整的接口。那可能吗?目前,我有:
type Fn<Values> = (part: string) => { [key in keyof Values]?: string }
type Item<Values> = string | Fn<Values>;
function extract<Values>(items: Item<Values>[]) {
const values = {} as Values;
// (...)
return values;
}
但是,这种类型只检查所有函数是否返回与键匹配的对象,Values
而不是所有键最终都存在。
我不太确定这种检查是否可以使用 TypeScript,我发现这个答案也适用于类型的“计算”,但我不确定这是否适用于这个用例。
解决方案
我非常有信心您可以编写任何类型,其成员是您想要的形式的数组。如果让 TypeScript 将数组的元素类型推断为其成员类型的并集,则可以验证元素类型是否覆盖了整个接口:
interface MyValues { foo: string; bar: string; }
// From jcalz, https://stackoverflow.com/a/50375286
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type Fn<Values> = (part: string) => { [key in keyof Values]?: string }
type Item<Values> = string | Fn<Values>;
type CheckComplete<Values, T extends Item<Values>> =
// note: ReturnType is distributive.
UnionToIntersection<ReturnType<Exclude<T, string>>> extends
{ [key in keyof Values]: string } ? unknown : never;
function extractFactory<Values>() {
return function<T extends Item<Values>>(items: T[] & CheckComplete<Values, T>) {
const values = {} as Values;
// (...)
return values;
};
}
const extract = extractFactory<MyValues>();
const a = [
'test-string',
foo => ({ foo }),
'other-string',
bar => ({ bar })
];
extract(a); // OK
const b = [
'test-string',
foo => ({ foo }),
'other-string'
];
extract(b); // Error
但是,使用将元素类型设置为联合的注释很容易绕过检查,并非所有成员都实际出现在数组中:
extract<string
| ((arg: string) => {foo: string})
| ((arg: string) => {bar: string})>(b); // Wrong but no error
推荐阅读
- javascript - 如何在网页上实现 javascript 模块化?
- mysql - MySQL 导入 - CSV - 文件拒绝正确导入
- java - 进度条 Android Studio Java
- reactjs - 在 React JS 中使用 Fluent UI Checkbox CSS
- d3.js - 在 D3 / Observable 中的 API 调用中使用 fetch 时出错
- excel - 尝试为 Excel 工作表中的每一行创建一个新的 XML 文档
- c++ - 错误:ISO C++ 禁止非常量静态成员的类内初始化解决方案::i -Tower Of Hanoi c++
- python - Pytest - 如何确保可变夹具保持不变?
- java - 如何在 Kotlin Gradle 脚本中导入 java 模块
- json - json解析后如何针对对象类型对字符串进行类型检查