Typescript实例化字符串联合类型



所以我有一个字符串并集类型

type S = 'a' | 'b' | 'c';

我想初始化一个S类型的值,同时断言它是S类型的。有了变量,这很容易:

const s1: S = 'a';
const s2: S = 'z'; // error

然而,我只想实例化值本身,沿着'a' as S的行,但检查'a'的类型为S

确切的用例是,我使用的是一个提供函数f(s: string)的库,但我想确保在调用它时,我只使用我认为可以的字符串来调用它。由于[afaik]不能从库外缩小签名范围,所以每次使用f时,我都想做类似f('a' as S)的事情。

定义我自己的函数g = (s: S) => f(s)不是一个好的选择,因为实际上f的签名看起来像f(s: string, t: T),其中T是一个复杂的库定义类型,我甚至不确定它是否被导出。

实现这一目标的最佳方式是什么?

使用字符串类型(TS操场(将外部函数与您自己的函数包装:

const externalFn = <T>(s: string, t: T) => t
type S = 'a' | 'b' | 'c';
const yourFn = (s: S, t: Parameters<typeof externalFn>[1]) => externalFn(s, t)

如果你需要处理一个有多个参数的函数,你可以使用这个答案中的想法(TS游乐场(:

type DropFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never
const externalFn = <T>(s: string, t: T) => t
type S = 'a' | 'b' | 'c';
const yourFn = (s: S, ...rest: DropFirst<Parameters<typeof externalFn>>) => externalFn(s, ...rest)

我最终制作了一个简单的包装器函数,如下所示:

function ok<T extends string>(s: T): T {
return s;
}

然后我可以像f(ok<S>('a'))一样使用它,因为在我的情况下,有多个函数和类型需要我进行验证,而制作一个单独的包装函数将是乏味的,并且不可维护。

相关内容

最新更新