typescript - 引用对象的属性名称和值对的类型的正确方法是什么?

标签 typescript

假设我有一个具有不同类型属性的对象。 TypeScript 中有没有办法让通用函数对对象的给定键和值执行操作?

这是一个例子。我有一个对象 s ,其中包含三个不同类型的字段:

interface Struct {
  a: string
  b: boolean
  c: string
}

const s: Struct = {
  a: 'hello',
  b: false,
  c: 'world',
}

假设我有一个函数可以使用以下属性之一执行某些操作:

function makeSetter<K, V>(name: K): (value: V) => void {
  return (value) => s[name] = value;
}

我应该如何参数化类型 KV 以便对于 makeSetter('a') 我会得到一个 类型的函数>(value: string) => void ,对于 makeSetter('b') 我会收到一个 (value: boolean) => void 类型的函数?

最佳答案

这里的技巧是使用通用约束。 K 必须是 keyof Struct,并且 V 必须可分配给 Struct[K]TypeScript docs

interface Struct {
  a: string
  b: boolean
  c: string
}

const s: Struct = {
  a: 'hello',
  b: false,
  c: 'world',
}

function makeSetter<K extends keyof Struct, V extends Struct[K]>(name: K): (value: V) => void {
  return (value) => s[name] = value;
}

// Helpers for type "unit tests"
type Equal<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false
function assertTrue<T extends true>() {}

const a = makeSetter('a')
const b = makeSetter('b')

assertTrue<Equal<typeof a, (value: string) => void>>() // No error
assertTrue<Equal<typeof b, (value: boolean) => void>>() // No error

关于typescript - 引用对象的属性名称和值对的类型的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56612980/

相关文章:

javascript - 删除搜索结果/angular2/typescript/js 中的重复值

javascript - 从 Api 返回的 Angular 5/6 搜索数据

typescript - TSLint:未使用的 var 关键字

Angular2 - 在检查时将检查值推送到数组

javascript - 如何停止执行 Firebase 触发的 Firebase 函数?

Angular 未捕获错误 : Can't resolve all parameters for service

javascript - 类型 'checked' 上不存在属性 'HTMLElement'。

typescript 接口(interface) : optional but not undefined

typescript - 无法匹配任何路由 : '' NativeScript, TypeScript 和 Angular2

javascript - 如何隐藏选项中的文本 ionic2