I want to get the type of arguments of a method like I get it from a function. This does not work:
function func(a: number, b: string): string {
return b;
}
type ftype = Parameters<typeof func>;
class Klasse {
method(a: number, b: string): string {
return b;
}
}
// this does not work
type mtype = Parameters<typeof klasse.method>;
And no, I don't want to transform method to a static method, it's just a simplified example.
---Edit---
The solution works, but not for overloads:
class Klasse {
method(a: string, b: number): void;
method(a: number, b: string): void;
method(a: number | string, b: number | string): string {
return 'x';
}
}
// this does not work
// type mtype = Parameters<typeof klasse.method>;
type mtype = Parameters<Klasse["method"]>;
const a: mtype = [0, ''];
const b: mtype = ['', 9]; // error
CodePudding user response:
The type Klasse
is the type of an instance of Klasse
.
type mtype = Parameters<Klasse["method"]>;
CodePudding user response:
As you observed, you can use the type utility Parameters<Type>
to derive a tuple of a function's parameters.
Because a function is a value in your program (not a type), deriving the type of the function requires using the typeof
operator, as shown below:
function func(a: number, b: string): string {
return b;
}
type F1 = Parameters<func>; /* Error
~~~~
'func' refers to a value, but is being used as a type here. Did you mean 'typeof func'?(2749) */
type F2 = Parameters<typeof func>; // ok
//^? type F2 = [a: number, b: string]
In JavaScript, classes are just special functions that we can write using language syntax sugar. Deriving the type of a class works the same way as with other functions: typeof Klasse
.
In order to refer to the type of an instance of the class, you can simply use the name of the class: TypeScript automatically creates a type name in scope that represents this when the class is in scope of your code: Klasse
.
TypeScript also provides another utility type for doing this:
InstanceType<Type>
Here's some code to demonstrate and juxtapose what I described above:
class Klasse {
method(a: number, b: string): string {
return b;
}
}
type KlasseKeys = keyof typeof Klasse;
//^? type KlasseKeys = "prototype"
type KlasseInstanceKeys = keyof Klasse;
//^? type KlasseInstanceKeys = "method"
type KlasseInstanceKeys2 = keyof InstanceType<typeof Klasse>;
//^? type KlasseInstanceKeys2 = "method"
type MethodParams = Parameters<Klasse['method']>;
//^? type MethodParams = [a: number, b: string]
type MethodParams2 = Parameters<InstanceType<typeof Klasse>['method']>;
//^? type MethodParams2 = [a: number, b: string]