遇到一个 ts 的问题,有更优雅的解决方案吗?

要求:尽量充分的利用类型推导,而不用额外写一写奇奇怪怪的东西。

问题点:

  1. func(str) 有正常的类型推导,很完美;
  2. func(obj.bbb) 为什么不能像前者一样?
type VmsType = "2D" | "3D" | "lpo" | "lips";

function func(type: VmsType) {
  console.log("🚀 ~ func ~ type:", type);
}

const str = "2D";
const obj = { bbb: "2D" };

// ok
func(str);
// Argument of type 'string' is not assignable to parameter of type 'VmsType'.
func(obj.bbb);

image.png

我知道可以下面两种办法:

  1. 类型断言(Type Assertion)

    func(obj.bbb as VmsType)
  2. 类型声明

    const obj: { bbb: VmsType } = { bbb: "2D" };

我想知道有没有更好的办法?

阅读 1.3k
4 个回答

因为 const str = '2D' 定义的是一个常量,不可能被修改,所以 str 的类型能自动推断为 '2D'
const obj = { bbb: '2D' } 中的 bbb 是一个可变成员, 所以只能往泛类型上推导成 string

这种场景最好用枚举

enum VmsType {
    '2D' = '2D',
    '3D' = '3D',
    lpo = 'lpo',
    lips = 'lips'
}

function func(type: VmsType) {
  console.log("🚀 ~ func ~ type:", type);
}

const str = VmsType["2D"];
const obj = { bbb: VmsType["2D"], ccc: 'test' };

// ok
func(str);
func(obj.bbb);
// Argument of type 'string' is not assignable to parameter of type 'VmsType'.
func(obj.ccc);

可以给obj添加上类型,这样ts就能推倒出其中属性类型:

type ObjType = {
    bbb: VmsType
}

const obj: ObjType = { bbb: '2D' }

// 此处就不会有ts报错了
func(obj.bbb)

对于obj的类型推断没有那么严格,只需要加强约束 就行了

const obj = { bbb: "2D" } as const;

type VmsType = "2D" | "3D" | "lpo" | "lips"

function func(type: VmsType) {
  console.log("🚀 ~ func ~ type:", type)
}

const str = "2D"
const obj = { bbb: "2D" as const }

// ok
func(str)
// Argument of type 'string' is not assignable to parameter of type 'VmsType'.
func(obj.bbb)
主要原因是 ts 只知道 2D 是字符串,不是 type 的枚举
logo
Microsoft
子站问答
访问
宣传栏