Can I make all the arguments of a function readonly and convert that function to an async function?
For example:
declare function foo<T>(bar: T, baz: T[]): T;
Convert to
declare function foo<T>(bar: Readonly<T>, baz: readonly T[]): Promise<T>;
I've tried this, which works for non-generic functions:
type ReadonlyArrayItems<T> = { [P in keyof T]: Readonly<T[P]> };
type MakeFunctionAsync<T> = (...args: ReadonlyArrayItems<Parameters<T>>) => Promise<ReturnType<T>>;
type Foo = MakeFunctionAsync<typeof foo>;
However, the new function type Foo
messes up the generic function by turning all the original generic type T
into unknown
.
P.S. Thanks for the answers.
However, is it possible to do this for all functions within an interface?
For example:
interface Methods {
foo<T>(bar: T, baz: T[]): T;
bar(baz: string): void;
}
Become this
interface Methods {
foo<T>(bar: Readonly<T>, baz: readonly T[]): Promise<T>;
bar(baz: string): Promise<void>;
}
If add another type based on the above:
type MakeFunctionsAsync<T> = {
[functionName in keyof T]: MakeFunctionAsync<T[functionName]>;
};
There doesn't seem to be a place to fill in the generic type parameter.
type MakeFunctionsAsync<T, U> = {
[functionName in keyof T]: MakeFunctionAsync<T[functionName]<U>>;
};
This won't work.
You should add a generic param to the Foo
:
declare function foo<T>(bar: T, baz: T[]): T;
type ReadonlyArrayItems<T> = { [P in keyof T]: Readonly<T[P]> };
type MakeFunctionAsync<T extends (...args: any[]) => any> = (...args: ReadonlyArrayItems<Parameters<T>>) => Promise<ReturnType<T>>;
type Foo<T> = MakeFunctionAsync<typeof foo<T>>;
To transform an interface you could use this (note that you need to have a generic interface to transform):
type ReadonlyArrayItems<T> = { [P in keyof T]: Readonly<T[P]> };
type MakeFunctionAsync<T extends (...args: any[]) => any> = (...args: ReadonlyArrayItems<Parameters<T>>) => Promise<ReturnType<T>>;
interface Methods<T>{
foo(bar: T, baz: T[]): T;
bar(baz: string): void;
}
type MakeFunctionsAsync<T extends Record<PropertyKey, any>> = {
[functionName in keyof T]: MakeFunctionAsync<T[functionName]>;
};
type Foo<T> = MakeFunctionsAsync<Methods<T>>;
const foo: Foo<string> = {
async foo(bar, baz){
return '';
},
async bar(baz){
return;
}
}