使用此链接中的函数类型示例-https://www.typescriptlang.org/docs/handbook/2/conditional-types.html

我不明白为什么在这种情况下不会发生类型缩小,而且如果不使用以下命令,返回类型就无法工作:

as NameOrId<T>;

在这种情况下,如何才能更好地编写给定的示例?

示例:

interface IdLabel {
  id: number;
}

interface NameLabel {
  name: string;
}

type NameOrId<T extends number | string> = T extends string ? NameLabel : IdLabel;

const createLabel2 = <T extends number | string>(nameOrId: T): NameOrId<T> => {
  if (typeof nameOrId === "string") {
    const result = {
      // why in this case type nameOrId
      // is (parameter) nameOrId: T & string
      // instead of symple string ??
      name: nameOrId,
    } 
    return result;
  }
  return {
    id: 123,
  } as NameOrId<T>;
};

推荐答案

让我们从数学集合论开始.根据Wikipedia:

在数学上,如果A的所有元素也是B的元素,则集合A是集合Bsubset;那么BAsuperset.AB是可能相等的;如果它们不相等,那么A就是Bsubset.一个集合是另一个集合的subset的关系称为inclusion(有时称为containment).空集也是任何集的子集.

Typescript 对并集、交集和赋值使用相同的逻辑.

例如,any是每种可能类型的superset,这意味着我们创建的每个原始、复杂、自定义类型都是any中的subset.

另一个例子是数字文字,假设number实际上是[-Infinity, +Infinity],它包括每个数字,我们有type A = 1.由于number包括A中的每个元素,Anumber的子集,这就是我们能够执行以下操作的原因:

let num: number = 1

字符串文字也是如此.string包含所有可能的字符串,但像type B = 'str'这样的文字只有一个潜在的值.

简而言之,您可以将子集类型为A的任何其他值赋给类型为A的变量.

当您处理非基元类型时,例如对象,超集是不太具体的类型:

type Superset = {a: string}
type Subset = {a: string; b: string}

Typescript 中的空集是never,由于空集是任何类型的子集,因此完全可以执行以下操作:

const a: number = {} as never;

现在,在泛型中,A extends B意味着A是子集B,而不是A等于B,因此编译器无法确定泛型参数的确切类型,当您判断类型保护时,它最多只能使其相交.

关于集合论的更多信息在这blog个Typescript 中

Typescript相关问答推荐

脉轮ui打字脚本强制执行图标按钮的咏叹调标签-如何关闭

从接口创建类型安全的嵌套 struct

Angular中的其他服务仅获取默认值

Angular 行为:属性类型从SignalFunction更改为布尔

具有泛型类型和缺省值的键

如何按不能保证的功能过滤按键?

如何使用WebStorm调试NextJS的TypeScrip服务器端代码?

了解类型规则中的关键字

缩小并集子键后重新构造类型

如何消除在Next.js中使用Reaction上下文的延迟?

防止重复使用 Select 器重新渲染

基元类型按引用传递的解决方法

回调函数中的TypeScrip类型保护返回Incorect类型保护(具有其他未定义类型的返回保护类型)

为什么在这种情况下,打字脚本泛型无法正确自动完成?

VUE 3类型';字符串';不可分配给类型';参考<;字符串&>

数据库中的表请求返回如下日期:2023-07-20T21:39:00.000Z 我需要将此数据格式化为 dd/MM/yyyy HH:mm

我应该使用服务方法(依赖于可观察的)在组件中进行计算吗?

如何确定剧作家中给定定位器的值?

如何在Typescript 中定义具有相同类型的两个泛型类型的两个字段?

Typescript 编译错误:TS2339:类型string上不存在属性props