【发布时间】:2020-03-30 05:01:35
【问题描述】:
我想正确键入以下对象。这里key是接口的键,T是字符串、数字或布尔值,E是一些键和字符串值的对象。问题是 E 对于对象的每个条目都不同,我想保留每个条目的类型信息。
{
[key]: (errorMessage?: E) => Validation<T, E>
}
例如,我可以有这样的东西。
interface StudentSchema {
name: string;
id: string;
country: string;
age: number;
}
interface Validation<T, E> {
foo: string;
bar: number;
validations: (errorMessages? E) => SchemaValidation<T>;
}
interface SchemaValidation<T> {
setIsRequired(message?: string) => SchemaValidation<T>;
setMatches(regex: any, message?: string) => SchemaValidation<T>;
setMax(max: number, message?: string) => SchemaValidation<T>;
isValid (data: T) => boolean;
}
class StringSchemaValidation extends SchemaValidation<string> { /* ... */ }
class NumberSchemaValidation extends SchemaValidation<number> { /* ... */ }
const StudentValidations: Record<keyof StudentSchema, Validation<T, E>> = {
name: {
foo: 'AAA',
bar: 1,
validation: (errorMessages?: { required: string }): SchemaValidation<string> =>
new SchemaValidation()
.setIsRequired(errorMessages?.required),
},
id: {
foo: 'BBB',
bar: 2,
validation: (errorMessages?: { required: string; match: string; max: (max: number) => string }): SchemaValidation<string> =>
new SchemaValidation()
.setIsRequired(errorMessages?.required)
.setMatches(/[a-zA-Z0-9]+/, errorMessages?.match)
.setMax(30, errorMessage?.max),
},
country: {
foo: 'CCC',
bar: 3,
validation: (errorMessages?: { required: string }): SchemaValidation<string> =>
new SchemaValidation()
.setIsRequired(errorMessage?.required),
},
age: {
foo: 'DDD',
bar: 4,
validation: (errorMessages?: { required: string }): SchemaValidation<number> =>
new NumberSchemaValidation()
.setIsRequired(errorMessage?.required),
},
};
首先,这不会编译,因为我没有为StudentValidations 指定E,但我不知道该放什么,因为每个条目都不同。我可以使用any 或类似的东西,但是当我访问validations 函数时,我会丢失类型信息。
我想要的本质上是将类型声明“委托”给实现,但这似乎是不可能的。有没有办法实现我想要的?或者,也许有不同的方法来实现这一点?
【问题讨论】:
-
您能否修改此代码以构成不依赖于“yup”的minimal reproducible example,除非您的问题专门针对该库?
-
也许this 适合你?
-
@jcalz 您可以完全忽略/替换 yup。它是什么并不重要。你提供的那个例子有效!但是,我希望能够将不同的接口传递给 ssVals。目前,它被硬编码为 StudentSchema ......是否可以将其推广到其他人?我也想不通。 (这对我来说有点像魔术)。
-
喜欢this?
-
如果您将示例更改为没有明显库依赖性的可回答问题,我很乐意将其写成答案。否则我的答案的前半部分将是我自己设置问题代码,以便我可以提供回答它的代码。
标签: typescript typescript-typings typescript-generics