技术解析

typescript 在 Object.entries 的回调中丢失了类型怎么办?
0
2021-08-27 12:32:45
idczone
type Vegetable = "茄子" | "黄瓜" | "西红柿"

type List = {
  [key in Vegetable]: {
    price: number;
    num: number;
  };
}

const list: List = {
  "茄子": {
    price: 5,
    num: 2
  },
  "西红柿": {
    price: 5,
    num: 2
  },
  "黄瓜": {
    price: 5,
    num: 2
  },
}

Object.entries(list).map(([key, item]) => {
  // 这儿的 key 不再是 Vegetable, 而是 string, 怎么能维持它的 Vegetable 类型呢?
})

运行在 Runtime 里的还是 JS 代码,所以你在运行时拿到的类型是 string。

可能我不会 ts,用 ts 有很多这样类似的问题
实在不行就

```javascript
Object.entries(list).map(([trueKey, item]) => {
let key1 = trueKey;
let key2 = trueKey as Vegetable;
})
```
实在没办法

entries 定义是
entries(o: { [s: string]: T } | ArrayLike): [string, T][];
entries(o: {}): [string, any][];
你得自己提供一个 entries 来 hack 这个 key 的类型

目前在 ts 里面构造出一个数组长度是一个对象 key 的数量,这种操作很难做通用实现
value 类型固定的,给个 xjb 的做法的话
在代码前面写一个
interface ObjectConstructor {
entries(o: O): [keyof O, O[keyof O]][];
}
后面的 entries 就能拿到类型了
但是我不推荐这样子写,因为不通用
如果场景足够单一,可以补充一个 entries 的定义,如果还有别的场景,建议手动指定 key 的类型

```
Object.entries(list).map(([key, item]: [Vegetable, { price: number; num: number }]) => {
// 可以给参数加个类型定义
});
```

没用,提示不能将 string 赋给 Vegetable

什么? ts 也设置类型? 前端高手不都是用 any 吗

没用,提示不能将 string 分配给 Vegetable 类型;
我确实是这样做的,但是如果很多地方要用到这个东西,每一处都要写很烦;
写这样的 interface 给我的感觉好像是 js 里面重写原型方法一样,不太喜欢这样写,虽然这样确实解决问题;

可能因为我菜吧 /(ㄒoㄒ)/~~

并不,他们不是一个概念,补充一个新的签名是重载,js 里面没有这个概念

不是说`重载`必须要将`函数定义`紧挨着`interface`写吗?还可以半中间插进来?王自如觉得很 awesome
数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服