首页 > 解决方案 > 基于键值约束对象的 Typescript 接口

问题描述

我是 Typescript 的新手,一直在玩。我有这段代码出现错误(为简单起见而缩减)。它最终是为了一个 redux 动作/reducer,这就是为什么它有点令人费解。

interface StoreType {
  bool: boolean,
  num: number,
}

interface PayloadType {
  key: keyof StoreType,
  value: ???
}

let test: PayloadType = {
  key: "bool",
  value: 3 // should ideally fail if value is not a boolean 
}

var obj: StoreType = { bool: true, num: 3 }

obj[test.key] = test.value // ts(2322) Type 'number' is not assignable to type 'never'

两部分问题:

  1. 是否有可能细化value为if类型和if类型?我试过了,但没有足够的约束:(PayloadTypetest.valuebooleantest.key == "bool"numbertest.key === "num"value: StoreType[keyof StoreType]

  2. 有没有办法使赋值obj[test.key] = test.value类型安全且无错误?我在https://github.com/microsoft/TypeScript/issues/31663中看到了错误,但我不确定如何继续,我不知道这是否与问题 1 有关。

如果我错过了一些基本的东西,我不会感到惊讶。

谢谢!

标签: typescriptreact-redux

解决方案


key将类型定义为具有约束PayloadType的泛型类型参数将起到作用:Kkeyof StoreType

interface PayloadType<K extends keyof StoreType> {
    key: K,
    value: StoreType[K]
}

let test: PayloadType<"bool"> = {
    key: "bool",
    value: true // ✅
}

let testError: PayloadType<"bool"> = {
    key: "bool",
    value: 3 // 
}

var obj: StoreType = { bool: true, num: 3 }

obj[test.key] = test.value

StoreType[keyof StoreType]不适用于此示例,因为keyof StoreType解析为联合类型"bool" | "num"。查找"bool" | "num"inStoreType将解析这些键的所有可能返回类型number | boolean

通过将 type 与一起声明key为泛型类型参数,您表示需要一个特定的键(不是联合)。KPayloadType<"bool">StoreType

操场


推荐阅读