typescript - 我可以定义一个模型,但需要一些字段的变化吗?
问题描述
对于我们的 API,您可以创建一个订单。该订单对于各种端点具有完全相同的模型,但变化的是所需的字段。
POST - 一些字段是必需的
PATCH - 所有字段都是可选的
PUT - 所有字段都是必需的
我可以在打字稿中对此进行建模,以便我只需要维护一个模型,然后提供有关 API 调用的一些信息来表示所需的字段吗?
解决方案
您可以在 make-required 或 make-optional 方向上专门使用映射类型执行此操作(感谢 TS2.8 中添加的用于删除映射类型中的修饰符的支持)。在不具体了解您要操作的类型或键的情况下,我会这样做:
// Require<T, K> takes an object type T and a set of its keys K
// and produces a new type identical to T except that the properties at keys K
// are now required. If K is left out, Require<T> behaves like Required<T>.
type Require<T, K extends keyof T = keyof T> = Pick<T, Exclude<keyof T, K>> &
Required<Pick<T, K>> extends infer U
? { [P in keyof U]: U[P] }
: never;
// Optionalize<T, K> takes an object type T and a set of its keys K
// and produces a new type identical to T except that the properties at keys K
// are now optional. If K is left out, Optionalize<T> behaves like Partial<T>.
type Optionalize<T, K extends keyof T = keyof T> = Pick<T, Exclude<keyof T, K>> &
Partial<Pick<T, K>> extends infer U
? { [P in keyof U]: U[P] }
: never;
这些基本上是彼此的镜像......它们使用一堆内置的映射类型,如Pick
、Partial
和Required
,以及一些自定义和内置的条件类型,如Exclude
. 这个想法是您将属性拆分T
为具有键的属性K
和没有键的属性。您修改 中的那些K
,不理会其他的,然后构建一个将所有属性重新组合在一起的新类型。让我们测试一下:
// Tests
interface AnInterface {
req1: string;
readonly req2: number;
readonly opt1?: boolean;
opt2?: object;
}
type SomeRequired = Require<AnInterface, "req1" | "opt1">;
// type SomeRequired = {
// readonly req2: number;
// opt2?: object | undefined;
// req1: string; // was already required, still is
// readonly opt1: boolean; // now required
// }
type SomeOptional = Optionalize<AnInterface, "req1" | "opt1">;
// type SomeOptional = {
// readonly req2: number;
// opt2?: object | undefined;
// req1?: string | undefined; // now optional
// readonly opt1?: boolean | undefined; // was already optional, still is
// }
那些对我来说看起来不错。当然,如果您不需要像这样的通用解决方案,您可以使用您的特定对象类型和键名执行相同或相似的类型映射。由你决定。
好的,希望有帮助;祝你好运!
推荐阅读
- php - SELECT 元素的未定义索引错误,但其格式与表单中的其他选择元素相同
- java - Discord bot JDA 不起作用,由 java.lang.ClassNotFoundException 引起
- javascript - 如何检测何时使用 jQuery 按下了删除键?
- java - Maven 没有在 Windows JDK 11 上运行,它说 JAVA_HOME 没有设置
- python - 如何在谷歌驱动API python中组合查询字符串
- opencv - 检测反射物体的边缘
- sql - posgresql - in 子句到布尔值
- java - 初学者Java项目:如何从数组中删除一个元素,当它是参数之一?
- reactjs - 在 React 中上传时无法预览图像
- excel - 根据行数和循环突出显示行