假设我有一个具有不同类型属性的对象。在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')
的功能?
答案 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下进行了描述。