Typescript 是如何改变方法定义的?
How does Typescript change the method definition?
Typescript 版本:"^2.9.2"
.
这是我的代码。
定义方法新接口:
interface TestRoute<R,F>{
to(r:R):F;
defaultRoute:F;
}
我的全局space:
declare global {
interface UserRpc {
connector: {
authRemoter:{
updateNickName:TestRoute<FrontendSession,typeof AuthRemoter.prototype.updateNickName>;
auth:TestRoute<FrontendSession,typeof AuthRemoter.prototype.auth>;
}
};
}
}
我定义的class:
@Component()
export class AuthRemoter extends RemoteAbstract{
constructor(@Inject(PROVIDERS.PINUS_APP) private readonly app:Application) {
super();
}
public async auth(username: string , password: string) {
return true;
}
public async updateNickName(uid:string,surname:string){
const connectionService = this.app.components.__connection__;
connectionService.updateUserInfo(uid,{username:surname} as any);
return true;
}
}
如何优雅地定义global.UserRpc.connector.authRemoter
接口,这样就不需要为每个方法调用TestRoute
?
谢谢。
如果您有要包含的方法名称列表,可以使用 mapped types 迭代它们并按照您想要的方式转换值:
type TestRoutify<T, K extends keyof T> =
{[P in K]: TestRoute<FrontendSession, T[K]>}
interface UserRpc {
connector: {
authRemoter: TestRoutify<AuthRemoter, 'auth'|'updateNickName'>
}
}
您可以验证此计算结果与上面代码中的 UserRpc
的类型相同。
如果您不想像 'auth'|'updateNickName'
那样手动列出方法名称,那么您需要一些方法从 AuthRemoter
类型中挑选这些名称。例如,如果您使用的标准是 "all methods of AuthRemoter
",那么您可以使用 conditional types:
来执行类似的操作
type FunctionKeys<T> =
{[K in keyof T]: T[K] extends Function ? K : never}[keyof T]
因此 FunctionKeys<AuthRemoter>
将评估为 'auth' | 'updateNickName'
以及 RemoteAbstract
中的任何额外方法名称。如果 RemoteAbstract
没有任何额外的方法或者您不介意包括它们:
type TestRoutifyMethods<T> = TestRoutify<T, FunctionKeys<T>>;
interface UserRpc {
connector: {
authRemoter: TestRoutifyMethods<AuthRemoter>
}
}
如果最终引入了您不想要的方法,那么您可以尝试想出一个能更好地代表您的选择标准的条件类型,或者干脆放弃并像第一个解决方案那样手动指定键多于。
希望对您有所帮助。祝你好运!
Typescript 版本:"^2.9.2"
.
这是我的代码。
定义方法新接口:
interface TestRoute<R,F>{
to(r:R):F;
defaultRoute:F;
}
我的全局space:
declare global {
interface UserRpc {
connector: {
authRemoter:{
updateNickName:TestRoute<FrontendSession,typeof AuthRemoter.prototype.updateNickName>;
auth:TestRoute<FrontendSession,typeof AuthRemoter.prototype.auth>;
}
};
}
}
我定义的class:
@Component()
export class AuthRemoter extends RemoteAbstract{
constructor(@Inject(PROVIDERS.PINUS_APP) private readonly app:Application) {
super();
}
public async auth(username: string , password: string) {
return true;
}
public async updateNickName(uid:string,surname:string){
const connectionService = this.app.components.__connection__;
connectionService.updateUserInfo(uid,{username:surname} as any);
return true;
}
}
如何优雅地定义global.UserRpc.connector.authRemoter
接口,这样就不需要为每个方法调用TestRoute
?
谢谢。
如果您有要包含的方法名称列表,可以使用 mapped types 迭代它们并按照您想要的方式转换值:
type TestRoutify<T, K extends keyof T> =
{[P in K]: TestRoute<FrontendSession, T[K]>}
interface UserRpc {
connector: {
authRemoter: TestRoutify<AuthRemoter, 'auth'|'updateNickName'>
}
}
您可以验证此计算结果与上面代码中的 UserRpc
的类型相同。
如果您不想像 'auth'|'updateNickName'
那样手动列出方法名称,那么您需要一些方法从 AuthRemoter
类型中挑选这些名称。例如,如果您使用的标准是 "all methods of AuthRemoter
",那么您可以使用 conditional types:
type FunctionKeys<T> =
{[K in keyof T]: T[K] extends Function ? K : never}[keyof T]
因此 FunctionKeys<AuthRemoter>
将评估为 'auth' | 'updateNickName'
以及 RemoteAbstract
中的任何额外方法名称。如果 RemoteAbstract
没有任何额外的方法或者您不介意包括它们:
type TestRoutifyMethods<T> = TestRoutify<T, FunctionKeys<T>>;
interface UserRpc {
connector: {
authRemoter: TestRoutifyMethods<AuthRemoter>
}
}
如果最终引入了您不想要的方法,那么您可以尝试想出一个能更好地代表您的选择标准的条件类型,或者干脆放弃并像第一个解决方案那样手动指定键多于。
希望对您有所帮助。祝你好运!