Is it possible to make "this" the generic type of the object? So, I have a following structure:
const obj = {
fn1: () => number,
fn2: (arg: number) => string,
fn3 (arg: string) => null
}
I want to type obj such that the functions params depend on each other:
export type Queries<T extends Q> = {
fn: () => any
decoder: (arg: ReturnType<T['fn']>) => any
transformationFn: (args: ReturnType<T['decoder']>) => any
}
Where Q is
type Q = {
fn: () => Promise<any>
decoder: (...args: any[]) => any
transformationFn: (...args: any[]) => any
}
now, if i use the following type signature:
const obj1: Queries
I would need to pass in a generic. But I can't pass in itself hence my question
CodePudding user response:
You're looking for type argument inference. To get that, I think you'll need a do-nothing function:
interface Queries<EncodedType, DecodedType, TransformedType> {
fn: () => EncodedType;
decoder: (arg: EncodedType) => DecodedType;
transformationFn: (arg: DecodedType) => TransformedType;
};
function makeQueries<EncodedType, DecodedType, TransformedType>(queries: Queries<EncodedType, DecodedType, TransformedType>) {
return queries;
}
// Works, because the types match
const good = makeQueries({
fn: () => Math.floor(Math.random() * 10000),
decoder: (arg: number) => String(arg),
transformationFn: (arg: string) => null,
});
// Error as desired, because they don't match
const bad = makeQueries({
fn: () => Math.floor(Math.random() * 10000),
decoder: (arg: number) => arg,
// ^−−− Type '(arg: number) => number' is not assignable to type '(arg: number) => string'.
transformationFn: (arg: string) => null,
});
CodePudding user response:
I'm not sure that is possible. But it's simpler and perhaps more idiomatic to use the relevant types as generic arguments directly:
export type Queries<FnReturnType, DecoderReturnType> = {
fn: () => FnReturnType
decoder: (arg: FnReturnType) => DecoderReturnType
transformationFn: (args: DecoderReturnType) => any
}
Or even more idiomatically and easier to read, as an interface:
export interface Queries<FnReturnType, DecoderReturnType> {
fn(): FnReturnType
decoder(arg: FnReturnType): DecoderReturnType
transformationFn(args: DecoderReturnType): any
}