Typescript 基于它获取对象类型';s属性值
我试图通过在聊天命令中引入静态约束来减少代码量和错误。 命令是用名称和参数描述的。以下是我得到的:Typescript 基于它获取对象类型';s属性值,typescript,typescript-generics,Typescript,Typescript Generics,我试图通过在聊天命令中引入静态约束来减少代码量和错误。 命令是用名称和参数描述的。以下是我得到的: type ArgumentTypeName='string'|'number'|'user'; type CommandArguments={[k in keyof T]:ArgumentTypeName}; 类型CommandHandler=(args:T)=>void; 类型命令={ 名称:字符串; 参数:命令参数; 处理程序:CommandHandler; } 我不知道如何从命令的参数中获
type ArgumentTypeName='string'|'number'|'user';
type CommandArguments={[k in keyof T]:ArgumentTypeName};
类型CommandHandler=(args:T)=>void;
类型命令={
名称:字符串;
参数:命令参数;
处理程序:CommandHandler;
}
我不知道如何从命令
的参数
中获取t
类型,因此它可以正确地影响处理程序
。
到目前为止,我得到了一个具有正确键的类型,但所有值都是未知的。像这样:
arguments={arg1:'string'}
//处理程序:(args:{arg1:unknown})=>void
我还试图约束参数
,认为如果我不指定t,它将从参数
中推断出来,但这不起作用:
type ArgumentName=
“我没有把绳子伸出来吗?”字符串':
“你的电话号码是多少?”编号':
T扩展用户?“用户':
从未;
类型CommandArguments={[k in keyof T]:ArgumentName};
类型CommandHandler=(args:T)=>void;
类型命令={
名称:字符串;
参数:命令参数;
处理程序:CommandHandler;
}
我如何根据它的属性CommandArguments
向后推断T
?所以我得到了
CommandArguments
→ <代码>T→ <代码>命令处理程序?还是有一种我没有想到的不同方法 编辑: 使用此选项的代码示例:
/*
在另一个文件中:
常量命令:命令[]=[];
导出函数createCommand(cmd:Command){
commands.push(cmd);
}
*/
createCommand({
名称:“添加”,
论据:{
a:‘数字’,
b:‘号码’
},
处理程序:(args)=>{
//(参数)参数:{a:未知;b:未知;}
//错误:对象的类型为“未知”。ts(2571)
console.log(args.a+args.b);
},
});
要从CommandArguments
推断CommandHandler
,我们可能不想做相反的事情,即在
type CommandArguments<T> = { [k in keyof T]: ArgumentName<T[k]> };
请分享您的
处理程序功能。我指的是使用这些types@captain-yossarian AddedAh,将CommandArguments
提升到最高点的想法不知怎的让我忘记了。谢谢你,这非常有效。
declare interface User{};
type ArgumentType<T> =
T extends 'string' ? string :
T extends 'number' ? number :
T extends 'user' ? User :
never;
type ArgumentTypeName = 'string' | 'number' | 'user';
type CommandArguments = { [k: string]: ArgumentTypeName };
type CommandHandler<T> = (args: { [k in keyof T]: ArgumentType<T[k]>}) => void;
type Command<T extends CommandArguments> = {
name: string;
arguments: T;
handler: CommandHandler<T>;
}
const commands: Command<any>[] = [];
export function createCommand<T extends CommandArguments>(cmd: Command<T>) {
commands.push(cmd);
}
createCommand({
name: 'add',
arguments: {
a: 'number',
b: 'string',
c: 'user',
},
handler: (args) => {
// (parameter) args: { a: number; b: string; c: User }
console.log(args.a.toPrecision(2) + args.b.padStart(30));
},
});