你如何声明一个变量持有一个通用委托?

时间:2017-06-13 21:42:15

标签: typescript generics delegates

不必在其他文件中重复委托的形状,如何声明对具有给定的已知类型形状的函数的引用?

功能:

/**
 * @param {object} prev
 * @param {object} next
 * @param {string} name - the name of the child param of both objects to compare
 */
exports.getModification = <T> (prev:T,next:T, name:string):Modification<T> =>
{
    const getIsChanging = p => prev[p] != null && p in next && next[p];
    const getIsAdding = p => !prev[p] && p in next && next[p];
    const getIsDeleting = p => prev[p] != null && p in next && !next[p];
    const result:Modification<T> = (
        getIsChanging(name) ? {changeType:'changing',next: next[name]}
        : getIsAdding(name)? {changeType:'adding', next: next[name]}
        : getIsDeleting(name) ? {changeType:'deleting',next:undefined}
        : {changeType:undefined,next:undefined});
    return result;
};

我试图通过

编写方法/委托的定义
interface Modification<T>{
    changeType: string | undefined;
    next: T | undefined;
}
interface GetModificationDelegate<T>{
    (prev:T,next:T, name:string) : Modification<T>;
}
// try a type alias
type GetModificationFunction<T> = (prev:T,next:T, name:string) => Modification<T>;

这两个编译都很好。但是,告诉typescript一个符号是对此的引用失败。

var getModification = (app.getModification as GetModificationFunction<T>);
var getModification: <T>GetModificationFunction<T> = app.getModification;
var getModification: <T extends{}>GetModificationFunction<T> = app.getModification;

没有编译。没有求助于类(我假设这很简单)我怎么能简单地告诉typescript什么是它已经知道的形状的泛型委托?

1 个答案:

答案 0 :(得分:1)

没有使用参数化类型声明值的语法,只有泛型函数有一个例外。

但如果你绝对需要,还有办法绕过这个限制。如果您对export使用es6 getModification语句而不是分配给exports,则可以沿着

方式导出其类型
export type GetModificationFunctionType = typeof getModification;

例如,&#34; m.ts&#34;的完整来源。模块是

export interface Modification<T>{
    changeType: string | undefined;
    next: T | undefined;
}


export const getModification = <T> (prev:T,next:T, name:string):Modification<T> =>
{
    const getIsChanging = p => prev[p] != null && p in next && next[p];
    const getIsAdding = p => !prev[p] && p in next && next[p];
    const getIsDeleting = p => prev[p] != null && p in next && !next[p];
    const result:Modification<T> = (
        getIsChanging(name) ? {changeType:'changing',next: next[name]}
            : getIsAdding(name)? {changeType:'adding', next: next[name]}
            : getIsDeleting(name) ? {changeType:'deleting',next:undefined}
            : {changeType:undefined,next:undefined});
    return result;
};

export type GetModificationFunctionType = typeof getModification;

你可以在另一个模块中使用它,例如&#34; d.ts&#34;:

import {Modification, GetModificationFunctionType} from './m';

var g: GetModificationFunctionType;

g = <T> (prev:T,next:T, name:string):Modification<T> =>
    ({changeType:undefined,next:undefined});

更新:如果只在某个类的上下文中需要该委托,则可以将其声明为类属性并具有该类的通用参数。但该属性不能是静态的:

class someClass<T> {
  delegate1: GetModificationDelegate<T>; // ok

  static delegate2: GetModificationDelegate<T>; //error: Static members 
                                        // cannot reference class type parameters  
}

泛型完全从生成的javascript代码中删除,而documentation states clearly静态成员声明无法引用泛型参数:

  

正如我们在关于课程的部分中所述,课程有两个方面   type:静态端和实例端。通用类只是   在他们的实例方面而不是他们的静态方面是通用的,所以   使用类时,静态成员不能使用类的类型   参数。

相关问题