Typescript 将函数参数匹配到类型映射的键和值
Typescript match function arguments to key and value of a type map
我有一个非常简单的案例,但我对 Typescript 打字的经验有限,我似乎无法解决这个看似简单的案例。
我有一个类型映射,例如:
interface KeyValueMap {
key: 'value';
foo: 'bar';
}
现在我想将函数的第一个和第二个参数键入上面映射的键和值
const test = <K extends keyof KeyValueMap>(key: K, value: KeyValueMap[K]) => {
switch (key) {
case 'key':
return value; // currently getting "KeyValueMap[K]" expecting "value"
case 'foo':
return value; // currently getting "KeyValueMap[K]" expecting "bar"
}
};
我试图搜索类似的案例,但我的 Google 似乎坏了...
因此,如果 Whosebug 上已经存在此类示例,则标记为重复时不会冒犯。
更新
在@ShivamSingla 对我的问题发表评论后,我意识到我的问题可能不够清楚。我对函数的 return 值不感兴趣,但已经希望在实际函数逻辑(在 switch-case 内)中识别该类型。我将更改示例以使其更清楚:
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
const test = <K extends keyof KeyObjectMap>(key: K, value: KeyObjectMap[K]) => {
switch (key) {
case 'foo':
return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
case 'bar':
return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
}
};
由于 key
和 value
没有关联,值可以是 re-assigned,在 switch case 之前。这就是错误的原因。请参阅 this 答案以获得更好的理解。
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
type K1 = keyof KeyObjectMap
const test = <K extends K1 = K1>(key: K, value: KeyObjectMap[K]) => {
// error here, 'key2' is missing
value = {
key1: 'value1',
}
// value is actually intersection, subtype `KeyObjectMap` actually
value = {
key1: 'value1',
key2: 'value2',
}
// since `key` and `value` are not associated, value can be re-assigned
// before switch case. That's why the error
switch (key) {
case 'foo':
return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
case 'bar':
return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
}
};
可能的解决方案
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
const test = <O extends Partial<KeyObjectMap>>(obj: O) => {
if (obj.foo) {
return obj.foo.key1
}
if (obj.bar) {
return obj.bar.key2
}
return undefined
};
// calling
const c = test({foo: {key1: 'value1'}})
我有一个非常简单的案例,但我对 Typescript 打字的经验有限,我似乎无法解决这个看似简单的案例。
我有一个类型映射,例如:
interface KeyValueMap {
key: 'value';
foo: 'bar';
}
现在我想将函数的第一个和第二个参数键入上面映射的键和值
const test = <K extends keyof KeyValueMap>(key: K, value: KeyValueMap[K]) => {
switch (key) {
case 'key':
return value; // currently getting "KeyValueMap[K]" expecting "value"
case 'foo':
return value; // currently getting "KeyValueMap[K]" expecting "bar"
}
};
我试图搜索类似的案例,但我的 Google 似乎坏了... 因此,如果 Whosebug 上已经存在此类示例,则标记为重复时不会冒犯。
更新
在@ShivamSingla 对我的问题发表评论后,我意识到我的问题可能不够清楚。我对函数的 return 值不感兴趣,但已经希望在实际函数逻辑(在 switch-case 内)中识别该类型。我将更改示例以使其更清楚:
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
const test = <K extends keyof KeyObjectMap>(key: K, value: KeyObjectMap[K]) => {
switch (key) {
case 'foo':
return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
case 'bar':
return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
}
};
由于 key
和 value
没有关联,值可以是 re-assigned,在 switch case 之前。这就是错误的原因。请参阅 this 答案以获得更好的理解。
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
type K1 = keyof KeyObjectMap
const test = <K extends K1 = K1>(key: K, value: KeyObjectMap[K]) => {
// error here, 'key2' is missing
value = {
key1: 'value1',
}
// value is actually intersection, subtype `KeyObjectMap` actually
value = {
key1: 'value1',
key2: 'value2',
}
// since `key` and `value` are not associated, value can be re-assigned
// before switch case. That's why the error
switch (key) {
case 'foo':
return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
case 'bar':
return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
}
};
可能的解决方案
interface KeyObjectMap {
foo: {
key1: 'value1';
};
bar: {
key2: 'value2';
};
}
const test = <O extends Partial<KeyObjectMap>>(obj: O) => {
if (obj.foo) {
return obj.foo.key1
}
if (obj.bar) {
return obj.bar.key2
}
return undefined
};
// calling
const c = test({foo: {key1: 'value1'}})