[英]TS infer from return type of callback property of an object parameter
我在尝试推断函数post
返回类型的类型时遇到了这个问题。 它的第二个参数是一个具有transform
属性的对象。 因此,如果提供了transform
参数,则post
的返回类型应该是transform
的返回类型,否则第一个为post
函数提供的第一个泛型类型。 我希望被理解。
type DefautlHttpCallInit = {
throttle?: number;
baseUrl?: string;
url?: string;
onSend?(e: HttpCallInit) : void | Promise<void>;
}
export type HttpCallInit = RequestInit & DefautlHttpCallInit
export type HttpCallInitOf<T> = RequestInit & DefautlHttpCallInit & {
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
}
})
编译器选项
{ "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" } }
您将泛型TOut
指定为转换本身的泛型,但这不是它所代表的,方法或函数上的泛型决定了它被调用时的行为。 您想在声明中指定转换输出类型(与T
位于同一位置),然后将其指定为post
函数的泛型, 如下所示:
export type HttpCallInitOf<T, TransformedType = unknown> = RequestInit & DefautlHttpCallInit & {
transform?: (v: T) => TransformedType
};
export type HttpCallerInstance = {
post<T, TransformedType = T>(data?: T, init?: HttpCallInitOf<T,TransformedType>): Promise<TransformedType>;
// TransformedType is defaults to T so if it can't be infered it stays as T
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.