在VS代码中使用TypeScript时,我无法通过使用否定的真实/错误缩小来推断对象的合并类型。
以下列例子为例:
// object union type
export type Result = { ok: true; value: 'foo' } | { ok: false; error: 'bar' };
const resolve = (): Result => ({ ok: false, error: 'bar'});
const result = resolve();
// narrowing on my machine works fine without negation
if (result.ok) console.log(result.value)
// narrowing with negation causes an error
if (!result.ok) console.log(result.error)我得到的错误是:Property 'error' does not exist on type '{ ok: true; value: void; } --这意味着联合类型没有被if语句缩小,并且没有发生任何推断。
这是不寻常的,因为在其他环境中,这种类型的缩窄确实有效,比如在这个沙箱里中否定的真实/错误的缩窄效果很好。
所以问题一定是我的环境,但是在我的环境中是什么导致了TypeScript的异常行为呢?更具体地说--我如何才能修复我的TypeScript缩窄?
有关我的环境的详细信息:
"typescript": "4.7.4""typescript.tsdk": "./node_modules/typescript/lib"发布于 2022-09-25 18:03:53
如果没有关于IDE环境的更详尽的信息,我只能猜测。但是,我认为您可以解决这个属性可访问性问题,同时保持类型安全而不进行更改。
在处理歧视结合时,典型的方法就是您所展示的:A | B。但另一种方法是将两种类型的所有属性都包含在每种类型中,并将每种类型的唯一属性设置为可选属性和never属性。
下面是一个如何使用几个类型实用程序来实现该功能的示例:
type ANotB<A, B> = A & Partial<Record<Exclude<keyof B, keyof A>, never>>;
type AOrB<A, B> = ANotB<A, B> | ANotB<B, A>;
type OKResult = { ok: true; value: 'foo' };
type NOKResult = { ok: false; error: 'bar' };
type Result = AOrB<OKResult, NOKResult>;
declare const result: Result;
if (result.ok) {
result.ok;
//^? (property) ok: true
result.error;
//^? (property) error?: undefined
result.value;
//^? (property) value: "foo"
}
if (!result.ok) {
result.ok;
//^? (property) ok: false
result.error;
//^? (property) error: "bar"
result.value;
//^? (property) value?: undefined
}使用这种方法,TypeScript不会阻止您使用点符号访问属性,该属性可能仅位于另一种联合类型中。在使用传统方法时,必须首先使用in操作符通知编译器该属性存在。
https://stackoverflow.com/questions/73846458
复制相似问题