typescript - 将 TypeScript 类型限制为仅允许的键,即 Exact/DeepExact
问题描述
这是对这个 SO question的后续尝试和模仿Exact type。
我想我有一些接近DeepExact
工作的东西:
// This is the good type/that we want to only accept Exact versions of
type Opts = {
firstName?: string;
parent?: string;
children?: { firstName?: string }[];
};
// This is the incoming type that has unknown fields which should be rejected.
type Args = {
firstName?: string;
parentId?: string;
children?: { firstName?: string; unknownField?: string }[];
};
const a: Args = null!;
// This compiles as expected but I want parentId and children.unknownField to cause type failures
const o: Opts = a;
// function that enforces only the exact Opts type
function onlyOpts<O>(o: Exact<Opts, O>): void {}
// good examples, using known fields
const g1 = { firstName: "f" };
onlyOpts(g1);
const g2 = { parent: "p", children: [{ firstName: "c1" }] };
onlyOpts(g2);
// bad examples, using unknown fields
const b1 = { firstName: "f", parentId: undefined };
onlyOpts(b1); // correctly fails b/c parentId is `never`
const b2 = { firstName: "f", children: [{ firstName: "c1", unknownField: "c1" }] };
onlyOpts(b2); // does not fail but should, unknownField is still `string`
// type alias to show B2["children"][]["unknownField"] is still string
type B2 = Exact<Opts, typeof b2>;
// Prototype Exact/DeepExact
type Exact<T, U> = T &
{
[K in keyof U]: K extends keyof T
? T[K] extends Array<infer TU>
? U[K] extends Array<infer UU>
? Array<Exact<TU, UU>>
: never
: U[K]
: never;
};
但我的b2
例子并没有失败,即深度/递归部分。该B2
类型仍然children
有 withunknownField: string
而不是unknownField: never
.
我认为单独推断TU
and UU
,然后将它们递归到Exact
会起作用,但由于某种原因它不是。
有任何想法吗?
解决方案
这目前适用于我的大多数琐碎测试用例:
export type Exact<T, U> = T &
{
[K in keyof U]: K extends keyof T
? T[K] extends Array<infer TU> | undefined | null
? U[K] extends Array<infer UU> | undefined | null
? Array<Exact<TU, UU>> | undefined | null
: never
: U[K]
: never;
};
但是在具有更深奥的泛型/用法/等的更大应用程序中失败了。所以仍在努力,但我基本上已经回答了我原来的问题。
推荐阅读
- swift - 深度优先搜索实现 - 理解 swift 代码
- r - 创建并绘制一个保留因子排序的表
- reactjs - 使用 Reactjs 触发 Cordova 相机插件
- java - 如何访问布局对话框中的项目?
- python - 加速 Python 脚本或寻找替代方案?
- c++ - 在 NodeJS 与 OpenSSL C++ 中加密时获得不同的值
- python-3.x - 如何访问内部的按钮在 python 中使用 selenium 的容器
- python - 如何在单个操作中展平具有已知分隔符的列表列表
- python - Gurobi Python中用于多维变量的KeyError
- python - 以 ip:port 格式解析工作“masscan”的结果