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