Typescript 为什么这个递归类型定义需要定义原语?

Typescript 为什么这个递归类型定义需要定义原语?,typescript,typescript-generics,Typescript,Typescript Generics,如果删除此类型上的注释行,为什么不编译 类型= T扩展数组)。特定的错误消息为 此条件将始终返回“false”,因为类型“DeepPartial”和“[number | string | boolean | bigint | symbol]”没有重叠 当将函数定义为函数测试(o:T)时,除了最后一个if语句外,其他所有语句都会收到类似的错误消息: 此条件将始终返回“false”,因为类型“T”和“[number | string | boolean | bigint | symbol]”没有重叠

如果删除此类型上的注释行,为什么不编译

类型=

T扩展数组)。

特定的错误消息为

此条件将始终返回“false”,因为类型“DeepPartial”和“[number | string | boolean | bigint | symbol]”没有重叠

当将函数定义为
函数测试(o:T)
时,除了最后一个
if
语句外,其他所有语句都会收到类似的错误消息:

此条件将始终返回“false”,因为类型“T”和“[number | string | boolean | bigint | symbol]”没有重叠

因为类型没有首先被区分,所以类型
T
test()
的主体中是一个不透明的类型,因此必须将其视为
未知的
,而不是
任何的

T
指的是类型的非均匀混合,这是不典型的,因此,如果这是您需要的,这可能是我建议的方法:

const enum Test {
  ONE,
  STRING,
  FALSE,
  BIG_ONE,
  HAS_INSTANCE,
  TWO,
  UNKNOWN
}

type TestMap<T> = T extends 1 ? Test.ONE
  : T extends '' ? Test.STRING
  : T extends false ? Test.FALSE
  : T extends 1n ? Test.BIG_ONE
  : T extends SymbolConstructor['hasInstance'] ? Test.HAS_INSTANCE
  : T extends 2 ? Test.TWO
  : Test.UNKNOWN;

function test<T>(o: T): TestMap<T> {
  function testImpl(o: any): Test {
    if (o === 1) return Test.ONE;
    if (o === '') return Test.STRING;
    if (o === false) return Test.FALSE;
    if (o === 1n) return Test.BIG_ONE;
    if (o === Symbol.hasInstance) return Test.HAS_INSTANCE;
    if (o === 2) return Test.TWO;
    return Test.UNKNOWN;
  }

  return testImpl(o) as TestMap<T>;
}
常量枚举测试{
一,,
一串
假,,
大一号,,
例如,,
二,,
不为人知
}
类型TestMap=T扩展1?测试一
:T扩展了“”?测试字符串
:T扩展为假?测试错误
:T扩展1n?测试,大一号
:T扩展符号构造函数['hasInstance']?Test.HAS\u实例
:T扩展到2?测试二
:Test.UNKNOWN;
功能测试(o:T):TestMap{
功能测试mpl(o:any):测试{
如果(o==1)返回测试1;
if(o=='')返回Test.STRING;
如果(o==false)返回Test.false;
如果(o==1n)返回测试,则返回大一;
if(o==Symbol.hasInstance)返回Test.HAS\u实例;
如果(o==2)返回测试2;
返回测试。未知;
}
将testImpl(o)作为TestMap返回;
}

特定的错误消息是

此条件将始终返回“false”,因为类型“DeepPartial”和“[number | string | boolean | bigint | symbol]”没有重叠

当将函数定义为
函数测试(o:T)
时,除了最后一个
if
语句外,其他所有语句都会收到类似的错误消息:

此条件将始终返回“false”,因为类型“T”和“[number | string | boolean | bigint | symbol]”没有重叠

因为类型没有首先被区分,所以类型
T
test()
的主体中是一个不透明的类型,因此必须将其视为
未知的
,而不是
任何的

T
指的是类型的非均匀混合,这是不典型的,因此,如果这是您需要的,这可能是我建议的方法:

const enum Test {
  ONE,
  STRING,
  FALSE,
  BIG_ONE,
  HAS_INSTANCE,
  TWO,
  UNKNOWN
}

type TestMap<T> = T extends 1 ? Test.ONE
  : T extends '' ? Test.STRING
  : T extends false ? Test.FALSE
  : T extends 1n ? Test.BIG_ONE
  : T extends SymbolConstructor['hasInstance'] ? Test.HAS_INSTANCE
  : T extends 2 ? Test.TWO
  : Test.UNKNOWN;

function test<T>(o: T): TestMap<T> {
  function testImpl(o: any): Test {
    if (o === 1) return Test.ONE;
    if (o === '') return Test.STRING;
    if (o === false) return Test.FALSE;
    if (o === 1n) return Test.BIG_ONE;
    if (o === Symbol.hasInstance) return Test.HAS_INSTANCE;
    if (o === 2) return Test.TWO;
    return Test.UNKNOWN;
  }

  return testImpl(o) as TestMap<T>;
}
常量枚举测试{
一,,
一串
假,,
大一号,,
例如,,
二,,
不为人知
}
类型TestMap=T扩展1?测试一
:T扩展了“”?测试字符串
:T扩展为假?测试错误
:T扩展1n?测试,大一号
:T扩展符号构造函数['hasInstance']?Test.HAS\u实例
:T扩展到2?测试二
:Test.UNKNOWN;
功能测试(o:T):TestMap{
功能测试mpl(o:any):测试{
如果(o==1)返回测试1;
if(o=='')返回Test.STRING;
如果(o==false)返回Test.false;
如果(o==1n)返回测试,则返回大一;
if(o==Symbol.hasInstance)返回Test.HAS\u实例;
如果(o==2)返回测试2;
返回测试。未知;
}
将testImpl(o)作为TestMap返回;
}

此外,调用
test(false)
不会产生编译错误,即使这些行被注释掉了。是的,我可以使用任何值调用函数,并且不会产生编译时错误,如果函数体更改为
returno,编译器知道在这种情况下返回类型是
false
此外,调用
test(false)
不会产生编译错误,即使这些行被注释掉了。是的,我可以使用任何值调用函数,它不会产生编译时错误,如果函数体更改为
returno,编译器知道在这种情况下返回类型是
false