typescript 扩展接口不允许覆盖 属性

typescript extending interface doesn't allow to overwrite property

Typescript 显然不允许我覆盖不需要的 属性。 我有几个接口:

interface IField {

  label:                string;
  model:                string;
  placeholder?:         string;
  addon?:               string;
  showOn?:              IDictionary <string | number>;
  maxlength?:           number;

}
interface ICheckboxField extends IField {

  model?:               string;
  type:                 'checkbox';
  default?:             string;
  options:              IOption[];
  validation?:    {
    required?:          string;
  };
}

因此,在 ICheckboxField 中,我将模型 属性 设置为不需要。 扩展 IField 的所有其他字段都需要具有必需的模型。

这是 Typescript 中的限制,还是除了不扩展接口而只添加专门用于接口的属性外,还有其他解决方案吗?

你可以做的是把 IFieldICheckboxField 的共享属性放在一个共享接口中:

interface IBase {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IField extends IBase {
    model: string;
}

interface ICheckboxField extends IBase {
    model?: string;
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}

另一种选择是将IField分成两个接口:

interface IField {
    label: string;
    placeholder?: string;
    addon?: string;
    showOn?: IDictionary;
    maxlength?: number;
}

interface IFieldOptionalModel extends IField {
    model?: string;
}

interface IFieldMandatoryModel extends IField {
    model: string;
}

interface ICheckboxField extends IFieldOptionalModel {
    type: 'checkbox';
    default?: string;
    options: IOption[];
    validation?: {
        required?: string;
    };
}

您试图覆盖严格类型 (IField),其中 属性 是强制性的,而较松散的类型 (ICheckboxField) 是强制性的。

编译器对此不以为然,但相反的情况是可能的:

interface Loose {
  label:string;
  model?:string;
}

interface Strict extends Loose {
  model:string;
}

var a:Loose = {
  label:"bar",
}

var b:Strict = {
  label: "baz",
  model: "me"
}

因此您可以在两者之上添加另一个接口,其中模型字段定义为可选,然后在 IField 中将其重新定义为必填。

另一个选项可能是使用 keyof 和查找类型 added in TypeScript 2.1