Typescript使用条件类型推断构造函数参数

Typescript infer constructor parameter using conditional types

类似于您如何通过类型推断使用Typescript来推断函数参数:

1
2
3
4
5
6
7
type FunctionProps< T > = T extends (arg1: infer U) => any ? U : never;

const stringFunc: (str: string) => string = (str: string): string => str;

type StringFuncType = FunctionProps<typeof stringFunc>;

const a: StringFuncType = 'a';

我想以相同的方式推断出构造函数参数,但到目前为止还没有成功。目前,我的设置如下:

1
2
3
4
5
6
7
8
9
10
type ConstructorProps< T > = T extends {
  new (arg1: infer U): T;
} ? U : never;

class Foo { constructor(a: string) {  } }

type FooConstructor = ConstructorProps<typeof Foo>;

// FooConstructor is always never but should be type string.
const a: FooConstructor = 'a'

无法确定Typescript中是否还支持此功能,因为TS文档中的"高级类型"部分仅提及函数,没有提及类(关于参数)。

还有其他人找到解决方案吗?


如果在构造函数的返回类型中将T更改为any,则该示例有效:

1
2
3
4
type ConstructorProps< T > = T extends {
  new (arg1: infer U): any;
//                     ^^^
} ? U : never;

请记住,T是构造函数的类型,与构造对象的类型不同。


如果不使用大括号,则可以使用,请参阅其他说明。

1
2
3
4
5
6
7
type ConstructorArgs< T > = T extends new(...args: infer U) => any ? U : never;

class Foo {
    constructor(foo: string, bar: number) { }
}

type Bar = ConstructorArgs<typeof Foo> // type Bar = [string, number]

查看关联的游乐场


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Test {
    constructor(foo: number, baz: string) {}
}

type FirstConstructorProp< T > = T extends {
  new (first: infer U, ...rest: any[]): any;
} ? U : never;

type F1 = FirstConstructorProp<Test>; // never
type F2 = FirstConstructorProp<typeof Test>; // number

type ConstructorProps< T > = T extends {
  new (...args: infer U): any;
} ? U : never;

type P1 = ConstructorProps<Test>; // never
type P2 = ConstructorProps<typeof Test>; // [number, string]