TypeScript Heisenbug driving me crazy: Excluding types with control statements.

huangapple go评论62阅读模式
英文:

TypeScript Heisenbug driving me crazy: Excluding types with control statements

问题

I simplified an error I was getting to a base case that sometimes reproduces on the TypeScript Playground, but usually it needs to be poked to be reproduced. It fails every time for me locally when running tsc.

type Result = {
  success: true,
  value: string,
} | {
  success: false,
  error: string,
};

const x = {success: true, value: 'hello'} as Result;
if (!x.success) {
  console.log(x.error);
}

TS Playground link

If you don't see an error on TypeScript Playground, click [TS Config] > and change Target. It doesn't seem to matter what I change it to. Change it to "ES2017" or "ES2019". This seems to trigger the error for me.

TypeScript Heisenbug driving me crazy: Excluding types with control statements.

Questions:

(1) Is there something wrong with the approach in the code or should TypeScript be handling it?

(2) Is there a decent workaround (short of casting directly everywhere)?

英文:

I simplified an error I was getting to a base case that sometimes reproduces on the TypeScript Playground, but usually it needs to be poked to be reproduced. It fails every time for me locally when running tsc.

type Result = {
  success: true,
  value: string,
} | {
  success: false,
  error: string,
};

const x = {success: true, value: 'hello'} as Result;
if (!x.success) {
  console.log(x.error);
}

TS Playground link

If you don't see an error on TypeScript Playground, click [TS Config] > and change Target. It doesn't seem to matter what I change it to. Change it to "ES2017" or "ES2019". This seems to trigger the error for me.

TypeScript Heisenbug driving me crazy: Excluding types with control statements.

Questions:

(1) Is there something wrong with the approach in the code or should TypeScript be handling it?

(2) Is there a decent workaround (short of casting directly everywhere)?

答案1

得分: 3

TypeScript 似乎不能正确地基于 ! 操作符进行缩小范围。如果您直接与联合类型的值进行比较,它可以正常工作 (playground 链接):

type Result = {
  success: true,
  value: string,
} | {
  success: false,
  error: string,
};

const x = {success: true, value: 'hello'} as Result;
if (x.success === false) {
  console.log(x.error);
}

这让我感到惊讶,基于不一致的结果,值得考虑提交一个 TypeScript 存储库问题

英文:

TypeScript does not appear to be properly narrowing based off of the ! operator. If you do a direct comparison against the value from your union, it works (playground link):

type Result = {
  success: true,
  value: string,
} | {
  success: false,
  error: string,
};

const x = {success: true, value: 'hello'} as Result;
if (x.success === false) {
  console.log(x.error);
}

This is surprising to me, and, based on the inconsistent results, it may be worth filing a TypeScript repo issue.

huangapple
  • 本文由 发表于 2023年3月7日 06:26:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656408.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定