Typescript:定义类型的对象,但根据需要推断提供的可选道具
想象一下这个配置对象:Typescript:定义类型的对象,但根据需要推断提供的可选道具,typescript,Typescript,想象一下这个配置对象: 接口节点图{ 键入:“圆”|“方”;//必须始终指定,没有默认值 颜色?:“红色”|“蓝色”;//有一个默认值,因此在输入时是可选的 效果?:“旋转”|“反弹”;//是完全可选的,不存在=没有效果 } 常量defaultNodeConfig:部分={ 颜色:“蓝色”, }作为常量; 函数drawNode(配置:NodeConfig){ const actualConfig={…defaultNodeConfig,…config}; //actualConfig.color
接口节点图{
键入:“圆”|“方”;//必须始终指定,没有默认值
颜色?:“红色”|“蓝色”;//有一个默认值,因此在输入时是可选的
效果?:“旋转”|“反弹”;//是完全可选的,不存在=没有效果
}
常量defaultNodeConfig:部分={
颜色:“蓝色”,
}作为常量;
函数drawNode(配置:NodeConfig){
const actualConfig={…defaultNodeConfig,…config};
//actualConfig.color的类型现在应该不可为空
//因为它是由defaultNodeConfig提供的
}
我想:
defaultNodeConfig
符合NodeConfig
接口,因此我不会在此处提供无效值(例如color:'black'
){…defaultNodeConfig,…config}
的类型,这样默认配置提供的属性就不再是可选的,我不必用打开它们代码>
- 当我指定了
时,它违反了第二个要求-类型是defaultNodeConfig:Partial
,因此NodeConfig&Partial
,没有任何关于NodeConfig
始终存在的线索color
- 当我删除类型声明
,第二个要求就如预期的那样得到了满足,但是:Partial
的类型不再受到约束,所以我可以将defaultNodeConfig
放在它上面{color:'black'}
有没有一种方法可以同时满足这两个需求,而不需要明确指定所有类型以及在哪一时刻哪些是可选的?类似于
constDefaultNodeConfig:Partial&typeof本身
(不,该语法不起作用)的内容,表示“约束常量以满足类型,但在使用常量时使用其推断类型”?这可能没有选项1所需的灵活,但如果只定义一次defaultNodeConfig,则可以使用与其内容匹配的自定义定义。在你的例子中是
const defaultNodeConfig :Required<Pick<NodeConfig, 'color'>> = {
color:'blue'
}
const defaultNodeConfig:必需={
颜色:'蓝色'
}
声明defaultNodeConfig类型后,脚本将在推断其他类型(如合并两个对象时)时使用该类型。在您的代码中,两个对象都被声明为具有可选颜色,因此结果类型也具有该定义,具有可选类型的值是合法的,因此结果对象仍然允许具有可选颜色。如果要创建的默认对象既有颜色又有效果,则可以将其声明为
const defaultNodeConfig :Required<Pick<NodeConfig, 'color'|'effect'>> = {
color:'blue',
effect:'spinning'
}
const defaultNodeConfig:必需={
颜色:'蓝色',
效果:“旋转”
}
如果您想从NodeConfig获得对defaultNodeConfig的更多限制,也可以使用
const defaultNodeConfig :Required<Pick<NodeConfig, 'color'>> & Partial<NodeConfig> = {
color:'blue'
}
const defaultNodeConfig:Required&Partial={
颜色:'蓝色'
}
这应该满足您的所有约束,但合并对象仍将具有可选效果,无论它是否在defaultNodeConfig中设置为要求
defaultNodeConfig
扩展Partial
,同时也是const
,您都可以使用泛型函数断言约束。以下方面应起作用:
const defaultNodeConfig = (<T extends Partial<NodeConfig>>(v: T) => v)({
color: 'blue',
})
constdefaultnodeconfig=((v:T)=>v)({
颜色:“蓝色”,
})
谢谢,就是这个!我将其抽象为constinferwithconstraint=()=>(v:T)=>v代码>。唯一的一个小缺陷是,您需要调用两级函数inferWithConstraint()(theGuardedValue)
,但这是可以接受的,因为它提供了我需要的所有优点!