Typescript条件验证取决于字段的可空性
我有以下代码:Typescript条件验证取决于字段的可空性,typescript,Typescript,我有以下代码: type DomainFieldDefinition<T> = { required?: boolean } type DomainDefinition<F, M> = { fields?: { [K in keyof F]: DomainFieldDefinition<F[K]> }, methods?: { [K in keyof M]: M[K] & Function }, } type User = { id
type DomainFieldDefinition<T> = {
required?: boolean
}
type DomainDefinition<F, M> = {
fields?: { [K in keyof F]: DomainFieldDefinition<F[K]> },
methods?: { [K in keyof M]: M[K] & Function },
}
type User = {
id: string,
name?: string
}
export const User = createDomain<User>({
fields: {
id: { required: true },
name: {},
},
});
我试图验证传递给某个字段的createDomain方法的定义对象中所需的键是否具有一个值,该值与它在此基于的类型的requiredness(用户)相匹配;最好是在编译时
我有一种感觉,条件类型可能有助于这样做,但我找不到一种基于需求的方法。具体地说,我试图约束以下要求:
如果该字段不可为空,则为true,
如果是,则为false或未定义
任何提示?使用定义为示例的类型,我们可以创建一个条件类型,其中如果字段是必需的,则字段类型将为{required:true}或{}类型,否则:
type DomainDefinition<F, M> = {
fields?: {
[K in keyof F]: ({} extends { [P in K]: F[K] } ? {} : { required: true }) & {} // Intersect with other properties as necessary
},
methods?: { [K in keyof M]: M[K] & Function },
}
type User = {
id: string,
name?: string
}
function createDomain<T>(o: DomainDefinition<T, any>) {
return o;
}
export const User = createDomain<User>({
fields: {
id: { required: true },
name: {},
},
});
如果要过滤掉某些属性,例如函数,则必须将所有出现的F替换为过滤后的F。要使其更简单,只需定义一个额外的类型别名:
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];
type DomainPropertyHelper<F> = {
[K in keyof F]: ({} extends { [P in K]: F[K] } ? {} : { required: true }) & {} // Intersect with other properties as necessary
};
type DomainDefinition<F, M> = {
fields?: DomainPropertyHelper<Pick<F, NonFunctionPropertyNames<F>>>,
methods?: { [K in keyof M]: M[K] & Function },
}
这是一个很好的答案,谢谢。不过,我还有一个问题;你的建议按原样运作。但是,每当我尝试用页面上定义的非功能属性名称将[K in keyof]替换为[K in NonFunctionPropertyNames]时,它就会失败。条件测试仅在发生该变化时为阴性。“你知道为什么吗,幸运的是?”Pierre添加了代码,使其能够与过滤一起工作
type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T];
type DomainPropertyHelper<F> = {
[K in keyof F]: ({} extends { [P in K]: F[K] } ? {} : { required: true }) & {} // Intersect with other properties as necessary
};
type DomainDefinition<F, M> = {
fields?: DomainPropertyHelper<Pick<F, NonFunctionPropertyNames<F>>>,
methods?: { [K in keyof M]: M[K] & Function },
}