typescript 当类型中有对象数组和其他属性时,类型脚本出错

kmb7vmvb  于 2023-01-10  发布在  TypeScript
关注(0)|答案(4)|浏览(210)

我有一个如下的对象

let Obj = {
['0'] : {
 mode: 'x'
},
getMode: () => 'x'
}

创建如下类型定义时出错

type Obj = {

[id: string]: {
mode: string
};
getMode: () => string

}

获取错误--类型为“()=〉string”的属性“getMode”无法分配给“string”索引类型“{ mode:字符串}'. ts(2411)

wd2eg0qa

wd2eg0qa1#

您使用的是索引签名,因此必须使用该签名指定其他类型。

type Obj = {
  [id: string]: { mode: string} | (() => string);
}

let Obj: Obj = {
  ['0']: {
    mode: 'x'
  },
  getMode: () => 'x'
}
yquaqz18

yquaqz182#

一开始这可能是违反直觉的,但是您所拥有的是getMode的两个相互排斥的定义
在类型Obj中,您有以下内容:

  • 一个通用的占位符键[id: string],基本上表示“任何字符串键都应该具有以下形状”(在本例中为{ mode: string }
  • 显式键getMode,其值的形状为() => string

由于第一个定义对于任何字符串键**都应该为真,因此它与第二个定义冲突,换句话说,getMode是字符串键,因此满足约束[id: string],这意味着它必须具有{ mode: string }的形状。
在类似的SO答案(如this one)中,将更深入地探讨此概念(以及潜在的解决方案

omqzjyyz

omqzjyyz3#

如果要使用具有{ mode: string }类型的通用键,则定义的具有string键类型(包括getMode)的所有属性都应具有{ mode: string }值类型。将getMode与通用键分离的一种方法是将Obj类型拆分为两部分:

type GetModeType = {
  getMode: () => string;
};

type GeneralType<T extends string> = {
  [P in T as T extends "getMode" ? never : P]: { mode: string };
};

然后根据它们的交集创建泛型类型:

type Obj<T extends string> = GetModeType & GeneralType<T>;

然后可以基于Obj类型创建对象:

const obj: Obj<"0" | "pending"> = {
  getMode: () => "hello",
  ["0"]: { mode: "zero" },
  pending: { mode: "this is pending mode." },
};

请注意,Obj类型具有() => string类型的getMode属性,并且您需要的另一个keys应该作为泛型类型(字符串字面值联合)传递。
您可以在typescript文档中阅读更多关于generic typesmapped types的信息。

6kkfgxo0

6kkfgxo04#

在Typescript中,[key: string]: type意味着所有的对象键都应该是该类型。

type Obj = {

[id: string]: {
mode: string
};
} & {
    getMode: () => string
}

相关问题