我有三种类型InputOptionPanel, SelectOptionPanel, CalcOptionPanel:的共同类型OptionPanel

export interface InputOptionPanelBase {
  _id: Types.ObjectId;
  required: boolean;
  value: string;
  group: string;
  title: string;
  optionGroup_id: string | undefined;
  position: number;
  editable: boolean;
  description?: string | null;
}

type InputOptionPanel = InputOptionPanelBase & { type: 'input' };
type SelectOptionPanel = InputOptionPanelBase & { type: 'select'; list: ISelectListItem[] };
type CalcOptionPanel = InputOptionPanelBase & { type: 'calc'; calc: Calc };

export type OptionPanel = InputOptionPanel | SelectOptionPanel | CalcOptionPanel;

Why does an error occur when declaring an object? enter image description here

第一个错误const newOption: OptionPanel -属性"calc"在选项面板类型中缺失,并且在CalcOptionPanel类型中是必需的

二误差

newOption.list = optionLists[option_id].map((listItem_id) => {
          const listItemDB = list.find((listItem) => listItem._id === listItem_id)!;
          return {
            title: getTextFromTitle(listItemDB.title),
            value: listItem_id,
            _id: listItem_id,
          };
        });

属性"list"不存在于类型"OpttionPanel"上. 类型"InputOptionPanel"上不存在属性"list".

我不明白如果我有通用类型,为什么会出现这些错误?这可能是三种类型之一.

export type OptionPanel = InputOptionPanel | SelectOptionPanel | CalcOptionPanel;

在第一个错误中,InputOptionPanel和SelectOptionPanel类型中缺少"calc"属性. 在第二个错误中,InputOptionPanel和CalcOptionPanel类型中缺少属性"list"

在我看来,这个错误是由于以下类型创建造成的:

type InputOptionPanel = InputOptionPanelBase & { type: 'input' };
    type SelectOptionPanel = InputOptionPanelBase & { type: 'select'; list: ISelectListItem[] };
    type CalcOptionPanel = InputOptionPanelBase & { type: 'calc'; calc: Calc };

推荐答案

这是因为在SelectOptionPanelCalcOptionPanel中,您有需要的计算和列表属性.因此,当您声明新对象时,ts不知道您的类型是inputcalcselect. 因此,您会收到一个错误,因为如果类型等于calc,您需要将calc字段传递给对象,如果您的类型为select,您需要传递列表字段.

如果您想解决这个问题,您需要在声明对象之前判断type变量的条件,以便ts可以识别正确的类型.我建议你这样做:

enum MyTypes {
  input = 'input',
  select = 'select',
  calc = 'calc'
}
type InputOptionPanel = InputOptionPanelBase & { type: Test.input };
type SelectOptionPanel = InputOptionPanelBase & { type: Test.select; list: ISelectListItem[] };
type CalcOptionPanel = InputOptionPanelBase & { type: Test.calc; calc: Calc};

export type OptionPanel = InputOptionPanel | CalcOptionPanel | SelectOptionPanel;

// declaring object for each type
if (type === MyTypes.select) {
  // your type is SelectOptionPanel and you need to define list property too
  const newOption: OptionPanel = {
    type, otherProperties, list: optionLists.map(yourMap)
}
}

Typescript相关问答推荐

界面中这种类型的界面界面中的多态性

如果在TypeScript中一个原始的类方法是递归的,如何使用类decorator 模式?

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

TypeScrip:基于参数的条件返回类型

如何使用Zod使一个基于其他字段值的字段为必填字段?

路由链接不会导航到指定router-outlet 的延迟加载模块

如何使默认导出与CommonJS兼容

参数属性类型定义的REACT-RUTER-DOM中的加载器属性错误

是否存在类型联合的替代方案,其中包括仅在某些替代方案中存在的可选属性?

以Angular 自定义快捷菜单

类型TTextKey不能用于索引类型 ;TOption

为什么Typescript不能推断类型?

在Cypress中,您能找到表格中具有特定文本的第一行吗?

17个Angular 的延迟观察.如何在模板中转义@符号?

有没有什么方法可以使用ProvideState()提供多个削减器作为根减减器

是否可以将类型参数约束为不具有属性?

JSX.Element';不可分配给类型';ReactNode';React功能HOC

递归JSON类型脚本不接受 node 值中的变量

如何使用 runInInjectionContext 中的参数测试功能性路由防护

将函数签名合并到重载中