无法为类型创建键入的快捷方式

时间:2018-06-17 01:28:33

标签: typescript

我在TS 2.9中有一个枚举:

export enum FMEvents {
  RECORD_ADDED = "@firemodel/RECORD_ADDED",
  RECORD_CHANGED = "@firemodel/RECORD_CHANGED",
  RECORD_MOVED = "@firemodel/RECORD_MOVED",
  RECORD_REMOVED = "@firemodel/RECORD_REMOVED",
}

它运作得很好。我 正在努力解决如何将字符串值作为约束/类型的问题,并且感谢jcalz我能够通过执行以下操作对此进行排序:

export type Extractable<T, U> = T extends U ? any : never;
export type NotString<T> = string extends T ? never : any;

现在我可以创建一个这样的函数:

doSomething<K extends string & NotString<K> & Extractable<FMEvents, K>>(type: K) { 
  //... 
}

&#34; type&#34;现在已正确约束到枚举的字符串(例如&#34; @ firemodel / RECORD_ADDED&#34;等)。剩下的唯一问题是在整个代码库中需要类型并且它非常满口,所以我想我可以在减少以这种方式约束所需的击键次数的同时给它一个更具描述性的名称。以下是我的想法:

export type IFMEventName<T> = T extends string & NotString<T> & Extractable<FMEvents, T>;

但这给了我以下错误。任何人都可以帮我弄清楚该怎么做?

enter image description here

1 个答案:

答案 0 :(得分:3)

哦,那是不合法的语法:

type A = B extends C; // error, ? expected

编译器将其解释为<{3}}的开头,如

type A = B extends C ? D : E;

并且可能会产生另一个错误,抱怨丢失的DE位置中无法移植的无名类型。错误是一个红色的鲱鱼,因为你根本就没有尝试使用条件类型。

您似乎正在尝试为conditional type创建类型别名,这也是无效的语法...通用参数名称和extends关键字可以&#39; t被移动到类型别名。

所以我猜你正在尝试这个:

// can't do this
export type IFMEventName<T> = T extends string & NotString<T> & Extractable<FMEvents, T>;
// also can't do this
function doSomething<IFMEventName<K>>(type: K) { /*...*/ } 

我很惊讶你没有看到各种其他错误......或许你是?无论如何,我认为你最接近你想要的是:

export type IFMEventName<T> = string & NotString<T> & Extractable<FMEvents, T>;
function doSomething<K extends IFMEventName<K>>(type: K) { /*...*/ }

希望这有意义并且适合你。祝你好运!