typescript 的提示问题, 如何才能解决ts报错混乱的问题?

目前遇到一个问题,如下图,报错中显示我的类型中 QuickCmp.Select 不能分配给 QuickCmp.Switch ,且 options 没有定义。而我这条代码的实际错误是,isGroup 没有在QuickSelect 中定义。
很明显,编辑器把 QuickSelect 的类型认成了 QuickSwitch ,以 QuickSwitch 的规则来校验这条数据
image.png

我试了以下两种方法来尝试解决这种问题:

  1. 删除图中所标示的代码,这时候就不会错认为QuickSwitch类型了
    image.png
  2. 调换了 QuickSelectQuickCmp.Switch 定义的顺序,这时候报错内容也是正确的
    image.png

虽然以上两种方法有效,但都是投机取巧,并不能解决实际工作中的问题。

以下是完整代码

export enum QuickCmp {
  Input = 'QuickInput',
  Radio = 'QuickRadio',
  Checkbox = 'QuickCheckbox',
  Select = 'QuickSelect',
  Switch = 'QuickSwitch',
}

export interface FormItemOptions {
  label: string;
  name: string;
  unchecked?: boolean;
  show?: object;
  inline?: [string, string]; 
}

export interface OptionsItem {
  label: number | string;
  text: any;
  [key: string]: any;
}

interface QuickCheckbox extends FormItemOptions {
  type: QuickCmp.Checkbox;
  defaultValue?: number | undefined | [];
  config: {
    options: Array<OptionsItem>;
  }
}

interface QuickInput extends FormItemOptions {
  type: QuickCmp.Input;
  defaultValue?: string | number;
}


interface QuickRadio extends FormItemOptions {
  type: QuickCmp.Radio;
  defaultValue?: string | number | boolean;
  config: {
    options: Array<OptionsItem>
  }
}

interface QuickSelect extends FormItemOptions {
  type: QuickCmp.Select;
  defaultValue?: string | number | boolean | Array<string | number | boolean>;
  config: {
    options: Array<OptionsItem>;
  }
}

interface QuickSwitch extends FormItemOptions {
  type: QuickCmp.Switch;
  defaultValue?: string | number | boolean;
  config?: {
    name?: string;
  }
}

export interface SlotOptions {
  slot: boolean;
  name: string;
}

export type FormItems = QuickInput | QuickSelect | QuickRadio | QuickCheckbox | QuickSwitch | SlotOptions;

const formOptions: Array<FormItems> = [
  { label: '文本框1', name: 'input1', type: QuickCmp.Input, defaultValue: 'heiheihie' },
  { label: '单选框1', name: 'radio1', type: QuickCmp.Radio, config: { options: []} },
  { slot: true, name: 'slot2'},
  { label: '下拉框2', name: 'select2', type: QuickCmp.Select, config: { options: [], isGroup: true } },
  { label: '开关1', name: 'switch2', type: QuickCmp.Switch, defaultValue: false, show: {radio1: 2} },
]

所以有懂的老师麻烦帮忙解答下如何才能实际的解决这个报错提示的问题,多谢多谢!!!

阅读 2.9k
1 个回答

QuickSelect 虽然固定了 type,但是 TypeScript 在拿 Literal Object 来匹配类型的时候,并不会根据其中一个属性来确定它的类型。

interface QuickSelect extends FormItemOptions {
    type: QuickCmp.Select;
    defaultValue?: string | number | boolean | Array<string | number | boolean>;
    config: {
        options: Array<OptionsItem>;
    }
}
{ label: '下拉框2', name: 'select2', type: QuickCmp.Select, config: { options: [], isGroup: true } },

在匹配上面这个字面对象的时候,config 的类型匹配不上,因为多了一个 isGroup: true。其实它和 QuickSwitch 也是匹配不上的,但是报错可能是直接拿最后一个匹配的类型来报的。这个先后顺序并不是很重要的,重要的是,它没匹配上你预定义的任何类型。

这里既然 config 可能包含除 options 之外的属性,那么

  • 如果知道有哪些,就定义到 QuickSelectconfig 类型里面去
  • 如果不知道,使用通配的属性类型 [key: string]: any

示例:

interface QuickSelect extends FormItemOptions {
    type: QuickCmp.Select;
    defaultValue?: string | number | boolean | Array<string | number | boolean>;
    config: {
        options: Array<OptionsItem>;
        [key: string]: any;
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题