是否可以 return 从参数传递给函数的泛型类型
Is it possible to return generic type from argument passed to a function
我已经对下面的代码进行了彻底的注释。我觉得像这样理解问题比试图用世界来解释它要容易得多。
abstract class BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD> {
constructor(public requestPayload: REQUEST_PAYLOAD) {}
// this method was only created for the sake of showing response1 type example
public return_RESPONSE_PAYLOAD_type(): RESPONSE_PAYLOAD {
return null;
}
}
type GetUserInfoRequest = { userId: number };
type GetUserInfoResponse = { username: string; age: number };
class GetUserInfoEvent extends BaseEvent<
GetUserInfoRequest,
GetUserInfoResponse
> {}
const emit = async <
REQUEST_PAYLOAD,
RESPONSE_PAYLOAD,
EVENT extends BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD>
>(
event: EVENT
): Promise<RESPONSE_PAYLOAD> => {
// some stuff will be done there - for the sake of example it was removed
return null;
// return event.return_RESPONSE_PAYLOAD_type(); // doesn't work aswell
};
const main = async () => {
const event = new GetUserInfoEvent({ userId: 666 });
const response1 = event.return_RESPONSE_PAYLOAD_type(); // type === { username: string; age: number; }
const response2 = await emit(event); // type === {} but I want it to be { username: string; age: number; }
// response2.username <-- error
// response2.age <-- error
// I want emit function to return current RESPONSE_PAYLOAD type instead of an empty object. I don't want to manually cast returned types to GetUserInfoResponse because I want to achieve 100% type safety.
};
main();
我应该不会,因为它是用 typescript@3.2.4
测试的。
Use 可以使用条件类型从 EVENT
中提取类型参数。通常不会根据另一个类型参数推断类型参数,您最终会得到尽可能窄的类型(在本例中 {}
)
abstract class BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD> {
constructor(public requestPayload: REQUEST_PAYLOAD) { }
// this method was only created for the sake of showing response1 type example
public return_RESPONSE_PAYLOAD_type(): RESPONSE_PAYLOAD {
return null;
}
}
type GetUserInfoRequest = { userId: number };
type GetUserInfoResponse = { username: string; age: number };
class GetUserInfoEvent extends BaseEvent<
GetUserInfoRequest,
GetUserInfoResponse
> { }
// Conditional type to extract the response payload type:
type RESPONSE_PAYLOAD<T extends BaseEvent<any, any>> = T extends BaseEvent<any, infer U> ? U : never;
const emit = async <
EVENT extends BaseEvent<any, any>
>(
event: EVENT
): Promise<RESPONSE_PAYLOAD<EVENT>> => {
// some stuff will be done there - for the sake of example it was removed
return null;
// return event.return_RESPONSE_PAYLOAD_type(); // doesn't work aswell
};
const main = async () => {
const event = new GetUserInfoEvent({ userId: 666 });
const response1 = event.return_RESPONSE_PAYLOAD_type(); // type === { username: string; age: number; }
const response2 = await emit(event); // is now GetUserInfoResponse
response2.username //<-- ok
response2.age //<-- ok
};
我已经对下面的代码进行了彻底的注释。我觉得像这样理解问题比试图用世界来解释它要容易得多。
abstract class BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD> {
constructor(public requestPayload: REQUEST_PAYLOAD) {}
// this method was only created for the sake of showing response1 type example
public return_RESPONSE_PAYLOAD_type(): RESPONSE_PAYLOAD {
return null;
}
}
type GetUserInfoRequest = { userId: number };
type GetUserInfoResponse = { username: string; age: number };
class GetUserInfoEvent extends BaseEvent<
GetUserInfoRequest,
GetUserInfoResponse
> {}
const emit = async <
REQUEST_PAYLOAD,
RESPONSE_PAYLOAD,
EVENT extends BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD>
>(
event: EVENT
): Promise<RESPONSE_PAYLOAD> => {
// some stuff will be done there - for the sake of example it was removed
return null;
// return event.return_RESPONSE_PAYLOAD_type(); // doesn't work aswell
};
const main = async () => {
const event = new GetUserInfoEvent({ userId: 666 });
const response1 = event.return_RESPONSE_PAYLOAD_type(); // type === { username: string; age: number; }
const response2 = await emit(event); // type === {} but I want it to be { username: string; age: number; }
// response2.username <-- error
// response2.age <-- error
// I want emit function to return current RESPONSE_PAYLOAD type instead of an empty object. I don't want to manually cast returned types to GetUserInfoResponse because I want to achieve 100% type safety.
};
main();
我应该不会,因为它是用 typescript@3.2.4
测试的。
Use 可以使用条件类型从 EVENT
中提取类型参数。通常不会根据另一个类型参数推断类型参数,您最终会得到尽可能窄的类型(在本例中 {}
)
abstract class BaseEvent<REQUEST_PAYLOAD, RESPONSE_PAYLOAD> {
constructor(public requestPayload: REQUEST_PAYLOAD) { }
// this method was only created for the sake of showing response1 type example
public return_RESPONSE_PAYLOAD_type(): RESPONSE_PAYLOAD {
return null;
}
}
type GetUserInfoRequest = { userId: number };
type GetUserInfoResponse = { username: string; age: number };
class GetUserInfoEvent extends BaseEvent<
GetUserInfoRequest,
GetUserInfoResponse
> { }
// Conditional type to extract the response payload type:
type RESPONSE_PAYLOAD<T extends BaseEvent<any, any>> = T extends BaseEvent<any, infer U> ? U : never;
const emit = async <
EVENT extends BaseEvent<any, any>
>(
event: EVENT
): Promise<RESPONSE_PAYLOAD<EVENT>> => {
// some stuff will be done there - for the sake of example it was removed
return null;
// return event.return_RESPONSE_PAYLOAD_type(); // doesn't work aswell
};
const main = async () => {
const event = new GetUserInfoEvent({ userId: 666 });
const response1 = event.return_RESPONSE_PAYLOAD_type(); // type === { username: string; age: number; }
const response2 = await emit(event); // is now GetUserInfoResponse
response2.username //<-- ok
response2.age //<-- ok
};