Typescript 抽象域上的其他道具被忽略

Typescript 抽象域上的其他道具被忽略,typescript,Typescript,当我将道具添加到一个类型时,当这些道具不是它们接口的一部分时,我希望看到TS的错误 如果您直接处理接口,这是可行的,但当类型来自抽象类时,它似乎只适用于必填字段 为什么会这样?我如何才能使验证按预期工作 interface IProps { foo: string; bar: number; } abstract class AbstractClass { protected abstract props: IProps; } class ConcreteClass extend

当我将道具添加到一个类型时,当这些道具不是它们接口的一部分时,我希望看到TS的错误

如果您直接处理接口,这是可行的,但当类型来自抽象类时,它似乎只适用于必填字段

为什么会这样?我如何才能使验证按预期工作

interface IProps {
  foo: string;
  bar: number;
}

abstract class AbstractClass {
  protected abstract props: IProps;
}

class ConcreteClass extends AbstractClass {
  constructor() {
    super();
  }

  protected props = {
    foo: "hello", 
    bar: 2,
    baz: true // <--- Why am I not getting 'baz' does not exist in type 'IProps'?
  };
}
接口IProps{
foo:string;
条:数字;
}
抽象类抽象类{
受保护的抽象道具:IProps;
}
类ConcreteClass扩展了AbstractClass{
构造函数(){
超级();
}
受保护道具={
福:“你好”,
酒吧:2,

baz:true/因为
ConcreteClass
中的
props
的推断类型是
IProps
的子接口,其中包括
baz
。您可以将子接口实例(和子类实例)分配给用超类型声明的变量,而不是相反的方式(因为反过来说,它们缺少属性)

要防止出现这种情况,您需要再次使用类型名称:

class ConcreteClass extends AbstractClass {
  constructor() {
    super();
  }
  protected props: IProps = {
  // *** Here -----^
      foo: "hello", 
      bar: 2,
      baz: true // Error: Type '{ foo: string; bar: number; baz: boolean; }' is not assignable to type 'IProps'.
  };
}

这与这样做不同:

let props: IProps;
// ...
props = {
    foo: "hello", 
    bar: 2,
    baz: true // Error: Type '{ foo: string; bar: number; baz: boolean; }' is not assignable to type 'IProps'.
};
…因为
ConcreteClass
正在声明
props
,而不是分配给已经存在的东西

或者,您可以将
props
定义为非
abstract
。这有点麻烦,因为您必须使用适当的默认值对其进行初始化。您可以将其声明为
IProps | undefined
,以避免:

abstract class AbstractClass {
  protected props: IProps|undefined = undefined;
}

class ConcreteClass extends AbstractClass {
  constructor() {
    super();
    this.props = {
        foo: "hello", 
        bar: 2,
        baz: true // Error: Type '{ foo: string; bar: number; baz: boolean; }' is not assignable to type 'IProps'.
    };
  }
}

…当然,也可以使用适当的默认值对其进行初始化,然后根据需要进行覆盖:

abstract class AbstractClass {
  protected props: IProps = {
      foo: "",
      bar: 42
  }
}

class ConcreteClass extends AbstractClass {
  constructor() {
    super();
    this.props.foo = "hello";
    this.props.bar = 2;
  }
}