我正在尝试处理打字稿中的模型验证。 我希望能够捕获验证定义的嵌套类型。
例如,我希望能够创建这样的验证器。
const validateUser = createValidator({
name: {
first: {
value: "First"
},
last: {
value: "Last"
}
},
age: {
value: 32
},
hasOnboarded: {
value: false
}
});
这将创建一个validateUser函数,该函数采用指定模型 类型并验证其类型。
我希望能够捕获类型,以便validateUser知道接受, 符合接口的对象。
type ValidateUser = typeof validateUser;
应输入
(
model: {
name: {
first: string,
last: string
},
age: number,
hasOnboarded: boolean
}
) => boolean
在TypeScript中可以吗?
答案 0 :(得分:3)
使用2.8的功能,条件类型和infer
关键字。
declare function createValidator<
T extends {
[key: string]: { value: any } | { [key: string]: { value: any } }
}>(modelDescriptor: T): (validationSubject: {
[key in keyof T]: T[key] extends { value: infer R }
? R
: {
[innerKey in keyof T[key]]: T[key][innerKey] extends { value: infer R } ? R : never
}
}) => boolean;
// const validateUser: (validationSubject: { name: { first: string; last: string; }; age: number; hasOnboarded: boolean; }) => boolean
const validateUser = createValidator({
name: {
first: {
value: "First"
},
last: {
value: "Last"
}
},
age: {
value: 32
},
hasOnboarded: {
value: false
}
});
让我们分解一下,因为这有点复杂。
首先,我们的函数接受类型参数T
,其约束是它必须是一个对象,其中每个键都必须是{value: any}
或嵌套对象,其中每个键都必须是{ {1}}。
我们的返回类型是一个对象,因此对于T中的每个键,我们都会检查该类型。如果它的类型为{value: any}
,则推断出{value: <whatever>}
(并称其为<whatever>
),则该键的值的类型为R(也就是{{1}下原始键的类型}键。
如果它不是R
类型,那么根据我们最初的约束,它必须是value
类型,因此返回类型成为对该内部对象的第二级映射,再次提取该类型嵌套对象{value: <whatever>}
中的任何内容。
如果都不是(由于我们的限制,这是不可能的),则密钥的返回类型将为{[key: string]: {value: <whatever>}}
。该部分永远都不能达到。