TypeScript泛型始终显示为“quot;任何;在VS代码中
我正在使用TypeScript 2.5.3和VS代码1.16.1,我正在尝试创建一个通用函数,该函数将接受一个事件处理程序,其中一个参数是一个特定类型,完成后它应该调用另一个类型的回调 例如:TypeScript泛型始终显示为“quot;任何;在VS代码中,typescript,generics,Typescript,Generics,我正在使用TypeScript 2.5.3和VS代码1.16.1,我正在尝试创建一个通用函数,该函数将接受一个事件处理程序,其中一个参数是一个特定类型,完成后它应该调用另一个类型的回调 例如: 路由器('staff count',异步函数(本地、有效负载、cb){ let staff=新员工(); cb(wait staff.count()); } ); 我的界面如下所示: export interface SocketCallback { <T>(json: T): void;
路由器('staff count',异步函数(本地、有效负载、cb){
let staff=新员工();
cb(wait staff.count());
} );
我的界面如下所示:
export interface SocketCallback {
<T>(json: T): void;
}
export interface SocketRouter {
(
eventName: string,
handler: {
<TdataIn>(
locals: string,
payload: TdataIn,
callback: SocketCallback
): Promise<void>;
}
): void;
}
class Staff {
public async count () { // no need to provide explicit return type. TS can infer.
return await 3; // would do some db interaction
}
}
let router: SocketRouter = function ( name, cb ) {
// Do something
}
router( 'staff-count', async function(locals, payload, cb) {
let staff = new Staff();
cb( await staff.count() ); // works as expected
} );
导出接口SocketCallback{
(json:T):无效;
}
输出接口插座计算机{
(
eventName:string,
处理程序:{
(
e:SocketLocals,
有效载荷:TdataIn,
回调:SocketCallback
):承诺;
}
):无效;
}
因此,我希望有效负载
是一个字符串
,而回调则是一个数字
但是,在VSCode中,它显示回调的所有三个文档都是:any
。如果我删除泛型
,它会显示TdataIn
和Tcallback
的数据类型,locals
和cd
也是正确的类型
在本例中,如何使负载
的类型为字符串
(它实际上是一个JSON对象,但为了保持简单…)
谢谢
编辑
以VS Code中的代码为例-删除
路由器的呼叫,它将显示有效负载作为TdataIn
的示例。将
保持在那里,它会将有效负载显示为任何。我想我应该是String
导出接口SocketCallback{
(json:T):无效;
}
输出接口插座计算机{
(
eventName:string,
处理程序:{
(
当地人:字符串,
有效载荷:TdataIn,
回调:SocketCallback
):承诺;
}
):无效;
}
班主任{
公共异步计数():承诺{
返回3;//将进行一些数据库交互
}
}
let路由器:SocketRouter=函数(名称,cb){
//做点什么
}
路由器(‘人员计数’、异步函数(本地、有效负载、cb){
let staff=新员工();
cb(wait staff.count());
} );
您的泛型在错误的位置
对于初学者来说,将泛型放在异步函数
的末尾是没有意义的,您可能指的是异步函数(){bla bla}as(somethine:Number,somethingElse:String)=>void
(即使这也没有意义)
然而,这里真正的问题是,应该一般推断的是回调,而不是处理程序本身(只是将其传递给回调)
你想要这样的东西:
export interface SocketCallback {
<T>(json: T): void;
}
export interface SocketRouter {
(
eventName: string,
handler: {
<TdataIn>(
locals: string,
payload: TdataIn,
callback: SocketCallback
): Promise<void>;
}
): void;
}
class Staff {
public async count () { // no need to provide explicit return type. TS can infer.
return await 3; // would do some db interaction
}
}
let router: SocketRouter = function ( name, cb ) {
// Do something
}
router( 'staff-count', async function(locals, payload, cb) {
let staff = new Staff();
cb( await staff.count() ); // works as expected
} );
导出接口SocketCallback{
(json:T):无效;
}
输出接口插座计算机{
(
eventName:string,
处理程序:{
(
当地人:字符串,
有效载荷:TdataIn,
回调:SocketCallback
):承诺;
}
):无效;
}
班主任{
公共异步计数(){//无需提供显式返回类型。TS可以推断。
return wait 3;//将执行一些数据库交互
}
}
let路由器:SocketRouter=函数(名称,cb){
//做点什么
}
路由器(‘人员计数’、异步函数(本地、有效负载、cb){
let staff=新员工();
cb(wait staff.count());//按预期工作
} );
重要的部分是:
SocketCallback
不再是泛型,而是由SocketCallback
接口表示的函数本身是泛型的。这种区别意味着可以通过传递给函数的参数推断类型参数(重命名为T)
- 因此,
处理程序
只有一个泛型类型参数
已编辑
将泛型参数放在SocketRouter
接口的方法上,然后可以在调用router
时指定泛型约束
export interface SocketCallback<T> {
(json: T): void;
}
export interface SocketRouter{
<TDataIn, TCallback>(
eventName: string,
handler: {(
locals: string,
payload: TDataIn,
callback: SocketCallback<TCallback>
): Promise<void>;
}
): void;
}
class Staff {
public async count (): Promise<number> {
return 3; // would do some db interaction
}
}
let router: SocketRouter = function ( name, cb ) {
// Do something
}
router<String, Number>( 'staff-count', async function(locals, payload, cb) {
let staff = new Staff();
cb( await staff.count() );
});
你的意思是函数(局部变量、有效负载:字符串、cb:number)
还是其他什么?我试图复制你的代码,但有很多类型丢失。您可以提供完整的吗?我正在尝试创建一个通用函数,该函数将接受一个事件处理程序,其中一个参数是特定类型的,完成后它应该调用另一个类型的回调。
@Igor-感谢您的回复。我现在为VS代码添加了一个完整的示例。我想做一个回调,因为这将在模块的顶层运行。嗨-谢谢你的回复!有了这段代码,VS代码将有效负载
视为TdataIn
,这很好,但我想让它知道,它应该是一个特定的JSON对象,我在别处已经定义为接口。这样VS代码就可以自动完成,TypeScript就可以进行类型检查。在那个例子中,泛型看起来根本没有被使用。我希望能够做一些事情,它会“知道”payload
是MyJSON
类型。在这种情况下,你告诉泛型函数,t必须扩展MyJSON
,比如:(json:t):void
@“Madara Uchiha”,我恐怕不明白。据我所知,这将在接口
定义中实现。但我只想告诉TypeScript/VSCode,对于路由器
函数的每次调用,有效负载
将是一个特定的JSON对象。一个可能是MyJSON
,另一个可能是StaffInfo
,等等。payload
是一个JSON对象,我想对其强制执行类型检查。我原以为这就是泛型的全部意义,但我不知道如果它总是在我给它一个