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

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 Playground Link

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

推荐答案

简短的回答是,TS4有一个PR.7用于此功能.与你的问题特别相关...

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描述以包含一个示例.

Comment here

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

这是在nightly build上的工作,注意你仍然需要一个运行时实现,不管它是否真的实现了任何东西都取决于你,它可能是一些不返回任何东西的模拟函数

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"`

My two-cents and more (More Post Script stuff)

我强烈建议调查他们type-fest岁以上的一些类型,如果你还没有的话.尤其地

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

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

编辑:使用声明合并和接口的变通方法

This is not dependent upon 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 Playground

Typescript相关问答推荐

PrimeNG Inputnumber,具有自定义号码格式器

具有条件通用props 的react 类型脚本组件错误地推断类型

如果我有对象的Typescript类型,如何使用其值的类型?

如何在方法中定义TypeScript返回类型,以根据参数化类型推断变量的存在?

有没有可能使用redux工具包的中间件同时监听状态的变化和操作

属性的类型,该属性是类的键,其值是所需类型

为什么我的Set-Cookie在我执行下一次请求后被擦除

不推荐使用Marker类-Google map API警告

如果字符串文字类型是泛型类型,则用反引号将该类型括起来会中断

如何在Reaction Query Builder中添加其他字段?

类型TTextKey不能用于索引类型 ;TOption

垫表页脚角v15

笛卡尔产品类型

声明文件中的类型继承

如何正确调用创建的类型?

抽象类对派生类强制不同的构造函数签名

如何在打字角react 式中补齐表格组

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

Svelte+EsBuild+Deno-未捕获类型错误:无法读取未定义的属性(读取';$$';)

定义一个只允许来自另一个类型的特定字符串文字的类型的最佳方式