首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么L扩展AUnion,R扩展AUnion没有重叠

为什么L扩展AUnion,R扩展AUnion没有重叠
EN

Stack Overflow用户
提问于 2022-01-09 12:58:51
回答 1查看 72关注 0票数 3

这与object {} === {}无关,

发现了这个问题不知道这是不是一样

类型集- AUnion不是空集。另外两种类型(LR)正在扩展它。我的理解是,这些L,R至少和AUnion一样宽,因此我期望L和R中的元素没有空的交点,即AUnion。

我丢失了TypeScript类型系统的哪一部分?

给定TypeScript代码

代码语言:javascript
运行
复制
type AUnion = 'a'|'b';
type Proc = <L extends AUnion, R extends AUnion>(l:L, r:R)=>0|1;
declare const proc:Proc;

可以用两个相同的参数调用proc。

代码语言:javascript
运行
复制
const arg:'a' = 'a';
proc(arg,arg); // this is fine (type-wise) 'a' does extend AUnion

据我所知,'a'等于'a'。它们的类型是aa扩展联合类型AUnion

让我们实现类型。

代码语言:javascript
运行
复制
const proc:Proc = (l, r)=>{
  if(l===r){
    return 0;
  }
  return 1;
}

然而TypeScript抱怨

代码语言:javascript
运行
复制
This condition will always return 'false' since the types 'L' and 'R' have no overlap.

操场连接

我错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-09 22:49:10

根据各种GitHub问题,错误的存在是有意的,但错误的确切措辞并不总是合适的。见微软/打字稿#25642微软/打字稿#27910微软/打字稿#41402

如果您有一个类型为X的值y和一个类型为Y的值y,那么是否允许x === y的规则是XY必须是“可比较的”。粗略地说,这意味着X extends YY extends X都是正确的。如果这两种情况都不是真的,那么x === y将被禁止。

众所周知,X extends ZY extends Z对于第三种类型的Z来说都是正确的,这一事实并没有改变这一点。实际上,类型顶型 In TypeScript,这意味着X extends unknownY extends unknown对于每个XY都是正确的。因此,XY被限制在某种普通的超级类型上,这并不意味着XY是否适合相互比较。

在您的例子中,L extends AUnionR extends AUnion,但是L extends RR extends L都不知道是真的。因此编译器不允许进行比较。

至于具体的错误信息的措辞,这是不好的。很明显,当x === yY没有“可比性”时,X“总是会返回X”,这是不正确的。当编译器说"XY没有重叠“时,听起来肯定是在说"X & Y就是never",但这当然不一定是真的。在这种情况下,总是会返回false (例如,如果Xstring,而Ynumber,或者X{z: string}Y{z: number})。

但是,X & Y的空虚并不是问题所在。编译器将阻止{x: string}{y: number}的比较,即使交集{x: string; y: number}绝对不是空的。因此,这种比较并不是真正阻止的,因为这两个值不可能是相同的;它是被阻止的,因为比较两种不直接相关的类型通常是错误的指示。

如果要比较编译器认为其类型“不可比较”的两个值,则始终可以将其中一个或两个值扩展为可比较类型。在您的例子中,您知道LR都可与AUnion相媲美,因此您可以执行以下操作

代码语言:javascript
运行
复制
const proc: Proc = (l, r) => {
  const _l: AUnion = l;
  const _r: AUnion = r;
  if (_l === _r) { // okay
    return 0;
  }
  return 1;
}

代码语言:javascript
运行
复制
const proc: Proc = (l, r) => {
  if (l as AUnion === r) { // okay
    return 0;
  }
  return 1;
}

操场链接到代码

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70641498

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档