gpt4 book ai didi

javascript - Typescript 拒绝不符合接口(interface)的属性

转载 作者:行者123 更新时间:2023-12-02 21:31:43 25 4
gpt4 key购买 nike

我有一个 API Controller ,它采用这样的主体参数

insertUser(@Body() user: IUser) {}

但是问题是我可以发布一个包含比 IUser 定义的更多属性的对象。

确保 user 严格遵守类型或克隆它仅保留接口(interface) IUser` 中定义的内容的最简单、最干净的方法是什么?

最佳答案

我的回答与框架无关。您询问如何强制 TS 不允许传递具有附加字段的类型的值,这意味着我们希望该类型具有独占行为,您具有相同的属性,否则您不允许。

首先,这种行为在类型级别上没有好处,就好像给定值具有我们需要的字段,那么其他字段对我们来说应该不重要。另一件事是,即使我们可以对类型进行编译时检查,如果您的数据来自 API,那么您需要在运行时级别进行验证。

首先是类型级别独占类型行为实现:

type IUser = {
name: string;
lastname: string;
}
// utility type to enforce exlusive type
type OnlyExistingFields<Champion, Pretendent> = {
[K in keyof Pretendent]: K extends keyof Champion ? Pretendent[K] : never
}

// example type with more fields
type IMoreUser = IUser & {
age: number;
}
// instance of correct type
const u1: IUser = {
lastname: '',
name: ''
}
// instance of type with more fields
const u2: IMoreUser = {
lastname: '',
name: '',
age: 12
}
// below type declaration of exlusive function
declare function insertUser<U extends OnlyExistingFields<IUser, U>>(user: U): void

// usage:
insertUser(u1) // 👍 correct type is the same
insertUser(u2) // 🔴 error type has more fields

上面是完全类型级别检查,我们只能传递特定类型的参数,不允许传递该类型的任何超集。

正如我所说,上面的解决方案只是类型级别,实际上,如果对象在运行时有或不需要接口(interface),则无法在类型级别强制执行,一切都只是假设。

也就是说,我们还需要运行时转换器才能删除所有不需要的字段。考虑这样的转换器:

// converts object with probably more fields to object with only wanted fields
function toIUser<T extends IUser>(a: T): IUser {
return {
name: a.name,
lastname: a.lastname
}
}
const u3 = toIUser(u2); // u3 is IUser and also in runtime has only IUser fields

关于javascript - Typescript 拒绝不符合接口(interface)的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60606650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com