【问题标题】:Typescript override super interface property doesn't work打字稿覆盖超级接口属性不起作用
【发布时间】:2019-03-13 08:48:48
【问题描述】:

我有如下界面:

interface Person {
  name: string;
  id: number;
  prop: number;
}

我想创建另一个扩展它的交错:

interface Person2 extends Person {
  prop: string;
}

但是,我想覆盖 prop 类型。我该怎么做?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    由于消费者依赖于多态属性,因此您无法更改派生接口中的类型。您可能还需要考虑其他选项。

    可以缩小派生接口中的类型:

    interface Person {
      name: string;
      id: number;
      prop: number | string;
    }
    
    interface Person2 extends Person {
      prop: string;
    }
    
    interface Person3 extends Person {
      prop: number;
    }
    

    然后您可以使用类型保护来检查 prop 的实际类型:

    function isPerson2(value: Person): value is Person2 {
        return typeof value.prop === "string";
    }
    
    function isPerson3(value: Person): value is Person3 {
        return typeof value.prop === "number";
    }
    
    function doSomething(value: Person) {
        if (isPerson2(value)) {
            //value is of type Person2 in here
        }
    }
    

    另一种选择是使Person 通用:

    interface Person<T> {
      name: string;
      id: number;
      prop: T;
    }
    

    这将使您可以选择应用 stringnumber 作为类型参数。

    您还可以在此解决方案中使用类型保护:

    function isPersonWithString(value: Person<string | number>): value is Person<string> {
        return typeof value.prop === "string";
    }
    
    function isPersonWithNumber(value: Person<string | number>): value is Person<number> {
        return typeof value.prop === "number";
    }
    

    【讨论】:

      【解决方案2】:

      你不能用接口做到这一点。

      好吧,如果您可以访问Person 接口,您可以进行这样的操作。把它分成两部分:

      interface PersonBase {
        name: string;
        id: number;
      }
      
      interface Person extends PersonBase {
        prop: number;
      }
      
      interface Person2 extends PersonBase {
        prop: string;
      }
      

      如果您无法更改原始界面并且不需要此以下是替换现有类型中现有密钥的技巧:

      type Person2 = Pick<Person, Exclude<keyof Person, 'prop'>> & {prop: string};
      

      或者,如果映射类型对您来说更清晰:

      type Person2 = {
        [K in Exclude<keyof Person, 'prop'>]: Person[K]
      } & {
        prop: string;
      }
      

      【讨论】:

        【解决方案3】:

        您可以在扩展基础(超级)接口之前省略碰撞道具:

        interface Person {
            name: string;
            id: number;
            prop: number;
        }
        
        type Omit<T, TKey extends keyof T> = Pick<T, Exclude<keyof T, TKey>>;
        
        interface Person2 extends Omit<Person, 'prop'> {
            prop: string;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-06
          • 2016-10-08
          • 1970-01-01
          • 2017-06-29
          • 1970-01-01
          • 1970-01-01
          • 2018-07-14
          • 2023-03-18
          相关资源
          最近更新 更多