typescript 索引签名的问题

发布于 2022-09-30 23:07:19 字数 397 浏览 26 评论 0

假如我想定义一个对象字面量一定包含isValid类型为boolean的属性,包含其他任意属性,属性名任意,固定为string类型:

type a = {
  isValid: boolean;
  [name: string]: string;
}

这样定义会报错,string不能兼容boolean

type a = 
{
  isValid: boolean;
}&{
  [name: string]: string;
}

这样定义不会报错,但使用的时候还是会报错

let b:a={isValid: false, name: 'name'};

我应该怎么写才能在定义和使用时都不会报错?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

止于盛夏 2022-10-07 23:07:19

没啥好办法,一旦使用了可索引类型(Indexable Type),索引签名和确定属性都必须是相同类型的子集。

所以你只能定义成:

type Foo = {
    isValid: boolean;
    [key: string]: string | boolean;
}

因为对于一个 JS 对象而言,确定属性也是可以通过索引签名形式访问的,即:

let m = obj.isValid;
let n = obj['isValid'];

这二者是等效的,所以它们的类型上一定得是包含和被包含的关系。

只不过这样写有一个比较麻烦的缺点,就是你往后要想取不是 isValid 的属性值,你只能类型断言一次才能当 string 用,就是会多写点儿代码了。


但有一种情况可以区分开,就是用 Symbol,因为 Symbol 的属性你没法直接“点”出来,它和索引签名可以同时存在:

const propSymbol = Symbol('isValid');

type Foo = {
    [propSymbol]: boolean;
    [key: string]: string;
}

const obj: Foo = { [propSymbol]: false, foo: 'bar' }; // ok
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文