Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript泛型始终显示为“quot;任何;在VS代码中_Typescript_Generics - Fatal编程技术网

TypeScript泛型始终显示为“quot;任何;在VS代码中

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;

我正在使用TypeScript 2.5.3和VS代码1.16.1,我正在尝试创建一个通用函数,该函数将接受一个事件处理程序,其中一个参数是一个特定类型,完成后它应该调用另一个类型的回调

例如:

路由器('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对象,我想对其强制执行类型检查。我原以为这就是泛型的全部意义,但我不知道如果它总是在我给它一个