在Python中定义"数据类"的实际方法是:要么使用内置的数据类模块,要么(为了更强大)使用pydantic库。
它们都解决了同样的问题:提供了定义和使用以数据为中心的类的能力(类只有很少或没有功能,只意味着存储和验证数据)。
pydantic的一个例子是:
class User(BaseModel):
id: int # required
name = 'John Doe' # optional with default
friends: List[int] = [] # optional, defaults to empty array
我可以通过添加验证器函数来检查最小字段长度等来扩展它。
我正在寻找与TypeScript类似的东西。这是我目前所学到的:
接口将是显而易见的选择,但它们只允许您定义数据结构,您不能使用接口来设置默认值
我已经研究了zod,但它看起来更多的是用于验证"未知"。数据。我无法使用
infer
功能生成正确返回默认数据的类型
我知道还有一些技巧,比如创建一个单独的函数来实现"overrides";
export type User = {
id: number;
name?: string;
};
export function generateUser(
props: User
): User {
const defaults = {
name: 'peter',
};
return {
...defaults,
...props
};
}
但这对我来说似乎有点复杂,因为我必须定义"默认字段"。两次(在类型和函数中)。它还有一个缺点,就是告诉typescriptname
是可选的,可能不存在。我希望始终存在,但如果没有指定其他内容,则使用默认值填充。
TypeScript是否提供了一种更优雅的方式来定义默认值?
我不确定这是否回答了你的问题,但是在TypeScript中,你可以使用一些helper泛型来修改任何给定的类型。例如,您正在寻找一个具体类型,其中name
总是被定义,但在函数输入中不需要。
我将这样定义类型:
- 为输入定义一个单独的类型,其中属性可以是可选的
- 让typescript决定
generateUser
函数的输出类型 - 如果您想在应用程序的其他部分使用
User
类型,您可以通过使用ReturnType<typeof generateUser>
获得该类型。
type UserInput = {
id: number;
name?: string;
};
export function generateUser (
input: UserInput
) {
return {
name: 'peter',
...input
};
}
type User = ReturnType<typeof generateUser>;
另一种解决方案是反过来做。我们定义了User
类型,因为它来自generateUser
函数,但修改了input
参数。
type User = {
id: number;
name: string;
};
type UserInput = Partial<Pick<User, 'name'>> & Omit<User, 'name'>;
export function generateUser (
input: UserInput,
): User {
return {
name: 'peter',
...input
};
}