在下面的代码中,如果我在函数调用时未明确指定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', () => ({}));
是否可以强制从T
参数中推断出obj
?
答案 0 :(得分:0)
它确实有效,您必须在Item
参数中传递一个create
。
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
答案 1 :(得分:0)
通过找到create
类型的obj
返回类型,我找到了一种解决方法:
function getOrPut<T>(
obj: { [key: string]: T | undefined },
key: string,
create: () => Exclude<typeof obj[string], undefined>
): T { ... }
不幸的是,由于某种原因,该解决方案仅在TypeScript 3.6.3
且当前版本为3.5.3
时才起作用,但应该尽快进行更新。我不确定这是否是最好的解决方案,也许有更好的解决方案。