从 TypeScript 中的模板文字类型中删除字符串

cas*_*asr 2 typescript

我已经能够将其表达为一个函数,以便foo返回末尾不带“Bar”的字符串。但是,如何使用该type语句来管理同样的事情呢?(见下文)

declare function foo<T extends string>(str: `${T}Bar`): T;
const justFoo = foo('fooBar');

// justFoo now exactly matches the type 'foo'

// What goes here?
type Foo<T extends string> = T;
type JustFoo = Foo<'fooBar'>;
Run Code Online (Sandbox Code Playgroud)

Ale*_*yne 10

您需要使用infer从该位置获取类型:

type Foo<T extends string> = T extends `${infer Prefix}Bar` ? Prefix : never;
Run Code Online (Sandbox Code Playgroud)

这表示检查字符串是否以 结尾"Bar",如果是,则推断小节之前字符串的内容并将其作为类型返回。如果字符串不以 结尾,"Bar"则将类型设置为never,这会在您尝试使用它时导致类型错误。

工作打字稿游乐场


您甚至可以限制泛型,使其永远不可能never

type Foo<T extends `${string}Bar`> = T extends `${infer Prefix}Bar` ? Prefix : never;
type JustFoo = Foo<'fooBar'>; // works
type ExpectErrorHere = Foo<'nofoofoyoo'> // error as expected
Run Code Online (Sandbox Code Playgroud)

在这个例子中:

T extends `${infer Prefix}Bar`
Run Code Online (Sandbox Code Playgroud)

不能为 false,因此never不会使用该子句。但是,infer 必须从条件类型中使用。所以你还是要检查一下。

操场