TypeScript类型获取受约束函数类型泛型的返回类型



基本上,我正在尝试找到一种方法,将函数类型用作泛型类型,以找到具有我选择的约束的函数的返回类型。然而,我不确定这是否可能,因为我不了解泛型函数参数在条件子句中是如何工作的。以下是我目前正在尝试的:

type FooFormatter = <S extends string>(input: S) => `foo-${S}`;
type StringFormatter = <S extends string>(input: S, ...args: never) => string;
type ComputeFormatter<Input extends string, T extends StringFormatter> =
T extends (input: Input, ...args: never) => `${infer $Value}`
? $Value
: never;
type foo = ComputeFormatter<"hey", FooFormatter>; // this is `foo-${string}` but I want "foo-hey"

TypeScript游乐场链接

ComputeFormatter中,我试图检查是否可以通过将函数的第一个参数重写为Input类型来以某种方式约束T中的泛型。谢谢你的帮助!

简言之,有一个为TS4.7合并的PR用于此功能。与你的问题特别相关。。。

type Box<T> = ReturnType<typeof makeBox<T>>;  // { value: T }

这非常接近#37181的解决方案。它会允许我们做…吗

return { value }; };
// Can we do it or something similar? Currently doesn't compile :(
type MakeBox<T> = ReturnType<typeof makeBox<T>>
// As it now allows us to do (no generics though)
const stringMakeBox = makeBox<string>; type MakeBox = ReturnType<typeof stringMakeBox>
// And even more relevant to support generics if we can now do: type
MakeBox = ReturnType<typeof makeBox<string>> 

是的,您确实可以使用该模式来捕获泛型函数的泛型返回类型。这在以前是不可能的。我将更新PR描述,以包含一个示例。

此处评论

我找不到任何关于这是适用于函数的类型别名,还是仅适用于运行时函数(用typeof推断(的信息,但您可能只使用实际的运行时实现,并根据需要使用typeof

这是关于夜间构建的工作,请注意,您仍然需要一个运行时实现,无论它是否真的实现了什么,都取决于您,它可能是一些不返回任何的模拟函数

type FooFormatter = <S extends string>(input: S) => `foo-${S}`;
const FooFormatterImplementation: FooFormatter = {} as any; //mock implementation
type StringFormatter = <S extends string>(input: S, ...args: never) => string;
type foo = ReturnType<typeof FooFormatterImplementation<"hey">>
//  ^? `type foo = "foo-hey"`

我的两美分及更多(更多后期脚本内容(

我强烈建议你调查一下他们在type-fest上的一些类型,如果你还没有的话。特别是

  • Split
  • 或者通常所有它们的CCD_ 8

通读库,你似乎对类型有很好的了解,我认为你实际上可能受到Deno的TS版本的限制。

有很多变通方法,但我不确定它们是否真的适用于您的用例。

  • https://stackoverflow.com/a/50006640/17954209
  • https://stackoverflow.com/a/62620115/17954209

编辑:使用声明合并和接口的解决方案

这与TS4.7无关万岁!

type FooFormatter = <S extends string>(input: S) => `foo-${S}`;
type BarFormatter = <S extends string>(input: S) => `bar-${S}`
export interface Formatters {
FooFormatter: FooFormatter,
BarFormatter: BarFormatter
}
// then anyone wanting to add a custom formatter, has to modify and reexport the interface,
// this is similiarly done in @react-mui, using module augmentation
// https://www.typescriptlang.org/docs/handbook/declaration-merging.html
function takeInnerTest<T extends string, FmtKey extends keyof Formatters>(input: T, formatter: FmtKey)
{
type formattersDiscriminated = {
[K in keyof Formatters]: Formatters[K]
}[FmtKey]
const __mockFunction: formattersDiscriminated = ((...args: any[]) => undefined) as any
const __mockReturn = __mockFunction(input)
type String = ReturnType<typeof __mockFunction>
type ReturnValue = Extract<typeof __mockReturn, String>
return null! as ReturnValue
}
const foo3 = takeInnerTest("hey", "FooFormatter")
type foo3 = typeof foo3
//  ^?
const foo4 = takeInnerTest("hey", "BarFormatter")
type foo4 = typeof foo4
//  ^?

TS游乐场

相关内容

  • 没有找到相关文章

最新更新