简体   繁体   中英

typescript extending interface doesn't allow to overwrite property

Typescript apparently doesn't allow me to overwrite a property being not required. I have a couple of interfaces:

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;
  };
}

So in the ICheckboxField I set the model property to be not required. All other fields that extend IField do need to have a required model.

Is this a restriction in Typescript or is there a solution other then not extending the interface and just adding the properties specifically for the interface?

What you can do is put the shared properties of IField and ICheckboxField in a shared interface:

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;
    };
}

Another option is to separate IField into two interfaces:

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;
    };
}

You trying to override a strict type ( IField ) where the property is mandatory with a looser type ( ICheckboxField ) where it's made mandatory.

The compiler frowns on that, but the opposite is possible:

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

interface Strict extends Loose {
  model:string;
}

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

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

So you could add another interface on top of both, where the model field is defined as optional and then redefine it as mandatory in IField .

Another option could be using keyof and the Lookup Types added in TypeScript 2.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM