在typescript中,如何将一种类型和另外两种类型的键建立在一起
设想一个函数getValidation接受某种状态和相应的模式来验证该状态。例如:在typescript中,如何将一种类型和另外两种类型的键建立在一起,typescript,typescript-typings,typescript-generics,Typescript,Typescript Typings,Typescript Generics,设想一个函数getValidation接受某种状态和相应的模式来验证该状态。例如: type State = { selectedColor: string selectedSize: string selectedOptions?: Record<string, string> } type StateSchema = { selectedColor: { required: (val: any) => boolean } selectedS
type State = {
selectedColor: string
selectedSize: string
selectedOptions?: Record<string, string>
}
type StateSchema = {
selectedColor: {
required: (val: any) => boolean
}
selectedSize: {
required: (val: any) => boolean
}
selectedOptions?: Record<string, { required: (val: any) => boolean }>
}
const state: State = {
selectedColor: '',
selectedSize: 'small',
}
const schema: StateSchema = {
selectedColor: {
required: (val: any) => Boolean(val)
},
selectedSize: {
required: (val: any) => Boolean(val)
}
}
const validation = getValidation(
schema,
state
)
// validation
{
$isValid: false,
$value: {
selectedColor: '',
selectedSize: 'small',
}
selectedColor: {
$isValid: false,
$value: '',
$validations: {
required: false
}
},
selectedSize: {
$isValid: true,
$value: 'small',
$validations: {
required: true
}
},
}
const state2 = {
selectedColor: '',
selectedSize: 'small',
selectedOptions: {
fit: 'tight',
length: ''
}
}
const schema2 = {
selectedColor: {
required: (val: any) => Boolean(val)
},
selectedSize: {
required: (val: any) => Boolean(val)
},
selectedOptions: {
fit: {
required: (val: any) => Boolean(val)
},
length: {
required: (val: any) => Boolean(val)
}
}
}
const validation2 = getValidation(
schema2,
state2
)
// validation2
{
$isValid: false,
$value: {
selectedColor: '',
selectedSize: 'small',
selectedOptions: {
fit: 'tight',
length: ''
}
}
selectedColor: {
$isValid: false,
$value: '',
$validations: {
required: false
}
},
selectedSize: {
$isValid: true,
$value: 'small',
$validations: {
required: true
}
},
selectedOptions: {
$isValid: false,
$value: {
fit: 'tight',
length: ''
},
fit: {
$isValid: true,
$value: 'tight',
$validations: {
required: true
}
},
length: {
$isValid: false,
$value: '',
$validations: {
required: false
}
},
},
}
类型状态={
selectedColor:字符串
selectedSize:字符串
所选选项?:记录
}
类型StateSchema={
所选颜色:{
必需:(val:any)=>布尔值
}
所选尺寸:{
必需:(val:any)=>布尔值
}
selectedOptions?:记录布尔值}>
}
常量状态:状态={
所选颜色:“”,
selectedSize:'小',
}
常量架构:StateSchema={
所选颜色:{
必需:(val:any)=>布尔值(val)
},
所选尺寸:{
必需:(val:any)=>布尔值(val)
}
}
const validation=getValidation(
模式,
状态
)
//验证
{
$isValid:false,
美元价值:{
所选颜色:“”,
selectedSize:'小',
}
所选颜色:{
$isValid:false,
$value:“”,
$validations:{
必填项:false
}
},
所选尺寸:{
$isValid:true,
$value:'小',
$validations:{
必填项:true
}
},
}
常量state2={
所选颜色:“”,
selectedSize:'小',
选择选项:{
适合:“紧”,
长度:“”
}
}
常量模式A2={
所选颜色:{
必需:(val:any)=>布尔值(val)
},
所选尺寸:{
必需:(val:any)=>布尔值(val)
},
选择选项:{
适合:{
必需:(val:any)=>布尔值(val)
},
长度:{
必需:(val:any)=>布尔值(val)
}
}
}
const validation2=getValidation(
方案2,
状态2
)
//验证2
{
$isValid:false,
美元价值:{
所选颜色:“”,
selectedSize:'小',
选择选项:{
适合:“紧”,
长度:“”
}
}
所选颜色:{
$isValid:false,
$value:“”,
$validations:{
必填项:false
}
},
所选尺寸:{
$isValid:true,
$value:'小',
$validations:{
必填项:true
}
},
选择选项:{
$isValid:false,
美元价值:{
适合:“紧”,
长度:“”
},
适合:{
$isValid:true,
$value:'紧',
$validations:{
必填项:true
}
},
长度:{
$isValid:false,
$value:“”,
$validations:{
必填项:false
}
},
},
}
以上示例需要注意的事项:
- 状态可以是用户定义的任何对象
- 模式结构必须与状态结构匹配,直到模式定义了一个对象,其中所有键都是验证状态中该点的函数李>
- 结果验证结构应与状态结构匹配,并添加一些内容$isValid和$value将为状态对象的每个级别添加。如果模式定义了验证器对象,则应将相应的验证器密钥添加到$validations密钥中
如何编写getValidation生成的验证的泛型类型或接口,这取决于状态和模式类型的结构 在你的问题中,我不确定你所说的“用户定义的任何对象”到底是什么意思,因为TypeScript类型只应用于编译时,而不是在运行时,因此如果用户只在运行时提供这些值,你就需要使用另一种方法 在这个回答中,我假设用户要么是使用您的框架的开发人员,要么是将用户所需的结构编码为TypeScript 您可以使用以下工具组合如下内容:
状态下将您的选项从一个记录交换为一个普通对象
类型,但其工作原理应该是相同的
type SchemaEntry=ObjectSchemaEntry | PrimativeSchemaEntry;
类型PrimativeSchemaEntry={
[验证名称:字符串]:(val:T)=>布尔值;
}
类型ObjectSchemaEntry={
[P in keyof T]:SchemaEntry;
}
类型架构={
[P in keyof T]:SchemaEntry;
}
类型ValidationResultEntry=
S扩展了ObjectSchemaEntry?ObjectValidationResultEntry:
你的计划是什么?PrimativeValidationResultEntry:
从未;
类型PrimativeValidationResultEntry={
$isValid:boolean;
$value:T;
$validations:{
[P in keyof S]:布尔值;
};
};
类型ObjectValidationResultEntry={
[P in keyof T]:验证结果;
} & {
$isValid:boolean;
$value:T;
};
类型验证结果={
[P in keyof T]:验证结果;
} & {
$isValid:boolean;
$value:T;
};
函数inferStateTypeFrom(){
返回(状态:S):S=>state;
}
函数inferSchemaTypeFrom(){
return(schema:S):S=>schema;
}
然后你可以像这样使用它
类型状态={
selectedColor:字符串
selectedSize:字符串
选择选项?:{[键:字符串]:字符串}
}
const state=inferStateTypeFrom()({
所选颜色:“”,
selectedSize:'小',
选择选项:{
适合:“紧”,
长度:“”
}
});
const schema=inferSchemaTypeFrom()({
所选颜色:{
必需:(val)=>布尔值(val)
},
所选尺寸:{
必需:(val)=>布尔值(val)
},
选择选项:{
适合:{
foo:(val)=>布尔值(val)
},
长度:{
条形图:(val)=>布尔值(val)
}
}
});
常量结果:ValidationResult={
$isValid:false,
美元价值:{
所选颜色:“”,
selectedSize:'小',
选择选项:{
适合:'',
长度:“”
}
},
所选颜色:{
$isValid:false,
$value:“”,
$validations:{
必填项:false
}
},
所选尺寸:{
$isValid:true,
$value:'小',
$validations:{
必填项:true
}
},
选择选项:{
$isValid:false,
美元价值:{
适合:'',
长度:“”
},
适合:{
$isValid:true,
$value:“”,
$validations:{
傅:是的
}
},
长度:{
$isValid:false,
$v