I am facing a challenge while trying to determine the return type for the function post
. The function's second parameter is an object that contains a transform
property. If the transform
parameter is provided, then the return type of post
should be the same as the return type of transform
. Otherwise, it should default to the first generic type provided for the post
function. I hope this explanation is clear.
type DefaultHttpCallInit = {
throttle?: number;
baseUrl?: string;
url?: string;
onSend?(e: HttpCallInit): void | Promise<void>;
}
export type HttpCallInit = RequestInit & DefaultHttpCallInit
export type HttpCallInitOf<T> = RequestInit & DefaultHttpCallInit & {
transform?: <TOut>(v: T) => TOut
};
export type HttpCallerInstance = {
post<T, TInit extends HttpCallInitOf<T>>(data?: T, init?: TInit): Promise<TInit extends {transform(e: T): infer XOut} ? XOut : T>;
}
//hack reference
let r = {} as HttpCallerInstance;
interface Post {
id?: number;
title: string;
}
interface User {
id: number;
userName: string;
}
interface UserPost extends Post{
user: User
}
const user = {/* info props */} as User;
r.post({title: 'New post'} as Post, {
//First: infer
transform(post) {
return Object.assign(post, {user}) as UserPost
}
})
Compiler Options
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "Latest",
"module": "ESNext",
"moduleResolution": "node"
}
}
Try it out on Typescript Playground
Here is the error message I encountered:
https://i.sstatic.net/tZXEx.png