TypeScript:从错误的参数推断出泛型函数类型参数
TypeScript: generic function type argument is inferred from a wrong parameter
在下面的代码中,如果我没有在函数调用时明确指定 T
,比如 getOrPut<Item>(...)
,它是从 create
参数推断出来的,因此创建的项目类型可能与 obj
字典不兼容,请参见代码的最后一行示例。
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => T
): T {
const value = obj[key];
if (value) {
return value;
} else {
return obj[key] = create();
}
};
type Item = { title: string };
type Dictionary = { [key: string]: Item };
const dictionary: Dictionary = {};
// the foo type is {} but I expect Item
const foo = getOrPut(dictionary, 'foo', () => ({}));
是否可以强制从 obj
参数推断出 T
?
它确实有效,你必须在 create
参数中传递一个 Item
。
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => T
): T {
const value = obj[key];
if (value) {
return value;
} else {
return obj[key] = create();
}
};
type Item = { title: string };
type Dictionary = { [key: string]: Item }
const dictionary: Dictionary = {};
// the foo type is {} but I expect Item{
const foo = getOrPut(dictionary, 'foo', () => ({} as Item)); // <--- casting here
我通过根据 obj
类型指定 create
return 类型找到了解决方法:
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => NonNullable<typeof obj[string]>
): T { ... }
不幸的是,由于某种原因,该解决方案仅适用于 TypeScript 3.6.3
,而我当前的版本是 3.5.3
,但它应该会尽快更新。我不确定这是最好的解决方案,也许有更好的解决方案。
在下面的代码中,如果我没有在函数调用时明确指定 T
,比如 getOrPut<Item>(...)
,它是从 create
参数推断出来的,因此创建的项目类型可能与 obj
字典不兼容,请参见代码的最后一行示例。
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => T
): T {
const value = obj[key];
if (value) {
return value;
} else {
return obj[key] = create();
}
};
type Item = { title: string };
type Dictionary = { [key: string]: Item };
const dictionary: Dictionary = {};
// the foo type is {} but I expect Item
const foo = getOrPut(dictionary, 'foo', () => ({}));
是否可以强制从 obj
参数推断出 T
?
它确实有效,你必须在 create
参数中传递一个 Item
。
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => T
): T {
const value = obj[key];
if (value) {
return value;
} else {
return obj[key] = create();
}
};
type Item = { title: string };
type Dictionary = { [key: string]: Item }
const dictionary: Dictionary = {};
// the foo type is {} but I expect Item{
const foo = getOrPut(dictionary, 'foo', () => ({} as Item)); // <--- casting here
我通过根据 obj
类型指定 create
return 类型找到了解决方法:
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => NonNullable<typeof obj[string]>
): T { ... }
不幸的是,由于某种原因,该解决方案仅适用于 TypeScript 3.6.3
,而我当前的版本是 3.5.3
,但它应该会尽快更新。我不确定这是最好的解决方案,也许有更好的解决方案。