一.场景
先来看一个业务场景
后端返回一个数组,数组里面描述了对象的状态,我们需要根据的状态去绑定样式或者class类
// 状态的枚举值
enum Status{
BEGIN, //开始
RUNNING, // 运行
ERROR//错误
}
const styleObj={
BEGIN: {
backgroundColor: '#fff'
},
RUNNING: {
backgroundColor: '#ccc',
opacity: 1
},
ERROR: {
backgroundColor: '#007bedff',
opacity: 0.5,
color: '#fff'
}
}
在template模板中需要这样操作
<template>
<div v-for='item in list' :key='item.id' :style="styleObj[Status[0]]"><>
</template>
问题
以上写法,如果是js的化,没有任何问题,但是我们用的是ts,ts会显示item.status 是anyl类型,不能作为styleObj 的键
二.思路及实现
我们首先考虑到的是限制styleObj的键,如何限制呢?
- 第一种方式:写死
interface IObj{
"BEGIN":unknown
"RUNNING":unknown
"ERROR":unknown
}
const styleObj:IObj={
BEGIN: {
backgroundColor: '#fff'
},
RUNNING: {
backgroundColor: '#ccc',
opacity: 1
},
ERROR: {
backgroundColor: '#007bedff',
opacity: 0.5,
color: '#fff'
}
}
- 第二种方式,使用类型计算
type map= typeof Status
type Tobj<T>={
[Prop in keyof T] :unknown
}
const obj:Tobj<map>={
BEGIN:{
color:'red'
},
RUNNING:{
color:"#00ff00"
},
END:{
color:"#ff0000"
}
}
但是当我们访问 styleObj[Status[0]] 仍然显示类型错误,ts并不知道,Status[0] 是什么,我们可以在这里做一次断言,styleObj[Status[0]] as keyof typeof Status
通过打印typeof Status
就可以得出“object”,枚举的本质是一个对象
,keyof 则是遍历对象的键,并进行联合。