以下代码导致错误:
example/not-following.ts:15:1 - error TS2722: Cannot invoke an object which is possibly 'undefined'.
15 run(true).maybe();
~~~~~~~~~~~~~~~代码:
interface Something {
maybe?: () => void;
}
function run(isTrue: boolean): Something {
const object: Something = {};
if (isTrue) {
object.maybe = (): void => {
console.log('maybe');
};
}
return object;
}
run(true).maybe();既然这是确定性代码,为什么TypeScript不遵循它呢?
发布于 2020-06-11 08:45:42
这个解决方案叫做generics:https://www.typescriptlang.org/docs/handbook/generics.html
interface Something {
maybe?: () => void;
}
function run<T extends boolean>(isTrue: T):
T extends true
? Something & Required<Pick<Something, "maybe">>
: Something {
const object: Something = {};
if (isTrue) {
object.maybe = () => {
console.log('maybe');
};
}
// @ts-ignore
return object;
}
run(true).maybe();
// @ts-expect-error
run(false).maybe();发布于 2020-06-10 08:47:28
我想TypeScript相当聪明,但可能不太聪明,以至于它完全验证了这些运行时执行路径。
作为另一种选择,您可以使用闭包,但我不确定这样的解决方案是否适合您。
interface Something {
maybe: () => void;
}
function run(isTrue: boolean): Something {
const object: Something = {
maybe: () => {
if (isTrue) {
console.log('maybe');
}
}
};
return object;
}
run(true).maybe();编辑:
由于我所收到的反对票(我不想反对),我还想指出,为了避免TypeScript中的错误,您需要:
maybe函数或我个人不喜欢可选字段,我个人不想乏味地将每个调用包装在一个检查if-block中。所以我个人还是更喜欢我现在的解决方案。
发布于 2020-06-10 08:53:19
不能调用可能是“未定义”的对象。
您会得到这个错误,因为maybe是可选的,类型记录无法知道是否定义了maybe。
要修复它,必须首先检查该属性是否存在:
interface Something {
maybe?: () => void;
}
function run(isTrue: boolean): Something {
const object: Something = { };
if (isTrue) {
object.maybe = (): void => {
console.log('maybe');
};
}
return object;
}
const oSomething: Something = run(true);
if (oSomething.maybe) {
oSomething.maybe();
}https://stackoverflow.com/questions/62299063
复制相似问题