TypeName的条件类型给出错误

时间:2020-02-16 23:19:50

标签: javascript typescript

以下类型来自TypeScript docs

export type TypeName<T> =
  T extends string ? 'string' :
  T extends number ? 'number' :
  T extends boolean ? 'boolean' :
  T extends undefined ? 'undefined' :
  T extends Function ? 'function' :
  'object';

但是尝试创建一个具有这种行为的函数会导致错误:

export type TypeName<T> =
  T extends string ? 'string' :
  T extends number ? 'number' :
  T extends boolean ? 'boolean' :
  T extends undefined ? 'undefined' :
  T extends Function ? 'function' :
  'object';

function typeName<T>(t: T): TypeName<T> {
  return typeof t; // ERROR: type '"string"' is not assignable to type 'TypeName<T>'
}

1 个答案:

答案 0 :(得分:0)

原因是条件类型不遵循函数内的控制流。

相关问题是:https://github.com/microsoft/TypeScript/issues/33912

例如以下(来自上述问题)导致了类似的错误:

type SomeConditionalType<T> = T extends string ? 1 : -1;
function fn<T>(arg: T): SomeConditionalType<T> {
    if (typeof arg === "string") {
        return 1; // ERROR: not assignable to SomeConditionalType<T>
    } else {
        return -1; // ERROR: not assignable to SomeConditionalType<T>
    }
}

解决方法

最简单的解决方法是在函数中使用类型断言,例如

export type TypeName<T> =
  T extends string ? 'string' :
  T extends number ? 'number' :
  T extends boolean ? 'boolean' :
  T extends undefined ? 'undefined' :
  T extends Function ? 'function' :
  'object';

function typeName<T>(t: T): TypeName<T> {
  return typeof t as TypeName<T>;
}