typescript - 测试缺少的接口属性
问题描述
我想检查一个对象是否实现了给定接口的所有属性。因为 TS 中的接口只是编译时构造,所以我需要列出所有要在运行时检查的属性。我使用了这个答案:https ://stackoverflow.com/a/60932900/10061195创建以下代码:
interface Test {
a: number,
b: number,
}
type CheckMissing<T extends readonly any[], U extends Record<string, any>> = {
[K in keyof U]: K extends T[number] ? never : K
}[keyof U] extends never ? T : T & "Error: missing keys"
type CheckDuplicate<T extends readonly any[]> = {
[P1 in keyof T]: "_flag_" extends
{ [P2 in keyof T]: P2 extends P1 ? never :
T[P2] extends T[P1] ? "_flag_" : never }[keyof T] ?
[T[P1], "Error: duplicate"] : T[P1]
}
// throw an error if the given object does not have all the properties of the given interface
function checkInterface<I, S extends (keyof I)[]>(val: any, keys: S & CheckMissing<S, I> & CheckDuplicate<S>): val is I {
const missing = keys.filter(k => val[k] === undefined);
if (missing.length > 0) {
throw new Error(`Missing properties: ${missing}`);
}
return true;
}
let val: unknown = { a: 5, b: 7 };
// ensure that the object val is of type Test
if (checkInterface<Test, ["a", "b"]>(val, ["a", "b"])) {
console.log(val.a);
}
它完全符合我的要求,除了我需要指定属性列表两次(一次作为模板参数,一次作为参数)。有没有办法只提供一次列表?
我尝试删除参数中的列表,但之后似乎无法从模板参数中检索列表。如果我删除模板参数,我将无法强制执行CheckDuplicate
and类型。CheckMissing
解决方案
推荐阅读
- android - 如何使用 Firestore 在 kotlin 中对数据进行分页?
- android - android.view.InflateException: Binary XML file line #48: Error inflating class TextView
- javascript - 如何在 Javascript 中插入具有 HTML 标记的 PHP 代码
- android - Android Studio:如何排除依赖库的特定包?
- python - 使用python将两个包含dict&list的json文件合并为单个json?
- html - 与语义 HTML 混淆
- python - 如何使这个 pygame 精灵的旋转(按中心)起作用?
- java - 如何使用最好的 android Volley 发布 JSON 数组并获取 JSON 对象作为响应?
- angular - 角度 4:ngb-dropdown-formcontrolName 不起作用
- python - 如何在 django 中使两个模型相互关联(反之亦然)。一个公司应该有多个目录,但一个目录只能有一个公司