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)
    ,但这是可以接受的,因为它提供了我需要的所有优点!