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

时间:2019-06-15 18:14:22

标签: typescript

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

这是一个例子。我有一个对象public static long calculate(List<Long> code) { long sequenceX = Long.parseLong("00000000", 2); long sequenceY = Long.parseLong("10101010", 2); long answer = Long.bitCount(sequenceX ^ sequenceY); System.out.println("Done: "+ answer); return answer; } ,其中包含三个不同类型的字段:

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; } K,以便对于V我将得到类型makeSetter('a')的函数,对于(value: string) => void我将收到一个类型为makeSetter('b')的功能?

2 个答案:

答案 0 :(得分:2)

这里的窍门是使用通用约束。 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

答案 1 :(得分:0)

Gerrit0的方法很有用。这是第二种有用的方法(that is also in the playground)。

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

const setter1 = makeSetter("a")("foo");
const setter2 = makeSetter("b")("foo"); // error
const setter3 = makeSetter("c")(false);

keyof T索引类型查询运算符,而T[K]索引访问运算符。两者都在“高级类型”文档的标题Index Types下进行了描述。