Typescript 递归补丁类型定义
我正在尝试编写一个泛型类型,它将一个类型作为参数(可以是普通对象、数组、基元等),并在它是普通对象或数组时重新映射值类型,以添加由Typescript 递归补丁类型定义,typescript,recursive-type,Typescript,Recursive Type,我正在尝试编写一个泛型类型,它将一个类型作为参数(可以是普通对象、数组、基元等),并在它是普通对象或数组时重新映射值类型,以添加由配置类型描述的一些配置指令 让我们称之为假设修饰符ConfigurableT可以是任何复杂嵌套的实体Book可以是T的值,例如: 类型配置={ $test:{ 选项1:布尔型; 选项2:字符串; } }; 打印本={ id:字符串; 标题:字符串; 作者:字符串; 相关:数组; }; 类型结果=可配置; 然后,我希望Configurable正确键入检查以下表达式,其
配置
类型描述的一些配置指令
让我们称之为假设修饰符Configurable
T
可以是任何复杂嵌套的实体Book
可以是T
的值,例如:
类型配置={
$test:{
选项1:布尔型;
选项2:字符串;
}
};
打印本={
id:字符串;
标题:字符串;
作者:字符串;
相关:数组;
};
类型结果=可配置;
然后,我希望Configurable
正确键入检查以下表达式,其中值可能是实际值或配置对象:
const expr1:可配置={
id:“1”,
标题:“哈利波特”,
作者:“J.K.罗琳”,
相关:[“2”、“3”]
}
常量expr2:可配置={
id:“2”,
标题:“哈利波特”,
作者:{
$test:{
选项1:正确,
选项2:“某物”
}
},
相关:[]
}
常量expr3:可配置={
id:“3”,
标题:“哈利波特”,
作者:“J.K.罗琳”,
相关:[“2”{
$test:{
选项1:正确,
选项2:“某物”
}
}]
}
常量expr4:可配置={
id:“4”,
title:true,//错误:应为字符串或配置
作者:“J.K.罗琳”,
相关:[“2”、“3”]
}
常量expr5:可配置={
id:“5”,
标题:“哈利波特”,
作者:“J.K.罗琳”,
相关的:{
$test:{
选项1:正确,
选项2:“某物”
}
}//错误:应该是(字符串|配置)的数组
}
嵌套对象或数组不应由配置
替换,仅在需要原语值的情况下(请参见expr5
)。
以下是我尝试过的:
类型配置={
$test:{
选项1:布尔型;
选项2:字符串;
};
};
类型可配置=记录扩展T
? {
[K in keyof T]:可配置|配置;
}
:T扩展数组
? 排列
:T;
但这会导致expr2
和expr3
失败
如果我正确理解您的需求,您可以使用
可配置的定义:
type Configurable<T> = T extends object ?
{ [K in keyof T]: Configurable<T[K]> } :
T | Configuration;
上面的示例编译时不会出现所需的错误。让我们检查错误:
const expr4: Configurable<Book> = {
id: "4",
title: true, // ERROR: should be string or Configuration
author: "J.K. Rowling",
related: ["2", "3"]
}
const expr5: Configurable<Book> = {
id: "5",
title: "Harry Potter",
author: "J.K. Rowling",
related: {
$test: {
option1: true,
option2: "something"
}
} // ERROR: should be an array of (string | Configuration)
}
const expr4:可配置={
id:“4”,
title:true,//错误:应为字符串或配置
作者:“J.K.罗琳”,
相关:[“2”、“3”]
}
常量expr5:可配置={
id:“5”,
标题:“哈利波特”,
作者:“J.K.罗琳”,
相关的:{
$test:{
选项1:正确,
选项2:“某物”
}
}//错误:应该是(字符串|配置)的数组
}
你想要的错误确实产生了。看起来不错
expr2expr2
不需要相关的属性吗?我在这里吃疯狂的药片吗?@jcalz是的,我错了。
const expr4: Configurable<Book> = {
id: "4",
title: true, // ERROR: should be string or Configuration
author: "J.K. Rowling",
related: ["2", "3"]
}
const expr5: Configurable<Book> = {
id: "5",
title: "Harry Potter",
author: "J.K. Rowling",
related: {
$test: {
option1: true,
option2: "something"
}
} // ERROR: should be an array of (string | Configuration)
}