Typescript 如何声明包含泛型委托的变量?

Typescript 如何声明包含泛型委托的变量?,typescript,generics,delegates,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)

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

功能:

/**
 * @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;
};
/**
*@param{object}prev
*@param{object}next
*@param{string}name-要比较的两个对象的子参数的名称
*/
exports.getModification=(prev:T,next:T,name:string):Modification=>
{
const getischange=p=>prev[p]!=next&&next[p]中的null&&p;
const getIsAdding=p=>!上一个[p]&下一个[p]中的p&p;
const getIsDeleting=p=>prev[p]!=next&&!next[p]中的null&&p;
常数结果:修改=(
GetIsChange(名称){changeType:'Changeing',next:next[name]}
:getIsAdding(名称){changeType:'adding',next:next[name]}
:getIsDeleting(名称){changeType:'deleting',next:undefined}
:{changeType:undefined,next:undefined});
返回结果;
};
我试图通过编写方法/委托的定义

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>;
接口修改{
changeType:字符串|未定义;
下一步:T |未定义;
}
接口GetModificationDelegate{
(上一个:T,下一个:T,名称:string):修改;
}
//请尝试键入别名
键入GetModificationFunction=(prev:T,next:T,name:string)=>Modification;
这两个都可以编译。然而,告诉typescript一个符号就是对它的引用是失败的

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

没有一个可以编译。如果不求助于类(我认为这样做很简单),我怎么能简单地告诉typescript某个东西是它已经知道的形状的泛型委托?

除了泛型函数之外,没有语法可以用参数化类型声明值

但是如果你绝对需要的话,有一种方法可以绕过这个限制。如果对
getModification
使用es6
export
语句,而不是指定给
exports
,则可以使用

export type GetModificationFunctionType = typeof getModification;
例如,“m.ts”模块的完整源代码是

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;
导出接口修改{
changeType:字符串|未定义;
下一步:T |未定义;
}
export const getmodify=(上一个:T,下一个:T,名称:string):modify=>
{
const getischange=p=>prev[p]!=next&&next[p]中的null&&p;
const getIsAdding=p=>!上一个[p]&下一个[p]中的p&p;
const getIsDeleting=p=>prev[p]!=next&&!next[p]中的null&&p;
常数结果:修改=(
GetIsChange(名称){changeType:'Changeing',next:next[name]}
:getIsAdding(名称){changeType:'adding',next:next[name]}
:getIsDeleting(名称){changeType:'deleting',next:undefined}
:{changeType:undefined,next:undefined});
返回结果;
};
导出类型GetModificationFunctionType=getModification的类型;
您可以在另一个模块中使用它,例如,“d.ts”:

import{Modification,GetModificationFunctionType}from./m';
var g:GetModificationFunctionType;
g=(上一个:T,下一个:T,名称:string):修改=>
({changeType:undefined,next:undefined});
更新:如果您仅在某个类的上下文中需要该委托,则可以将其声明为类属性,并具有该类的泛型参数。属性不能是静态的,但是:

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

  static delegate2: GetModificationDelegate<T>; //error: Static members 
                                        // cannot reference class type parameters  
}
class-someClass{
delegate1:GetModificationDelegate;//确定
静态delegate2:GetModificationDelegate;//错误:静态成员
//无法引用类类型参数
}
泛型从生成的javascript代码中完全删除,静态成员声明不能引用泛型参数:

正如我们在关于类的章节中所述,类有其两面性 类型:静态端和实例端。泛型类仅适用于 泛型在实例端而不是静态端,所以 使用类时,静态成员不能使用类的类型 参数


我可以把消费者声明封装在一个类中吗?将属性/静态方法定义为
GetModificationFunctionType
?是的,您可以在类中有声明,但不能是静态的。我更新了答案。
class someClass<T> {
  delegate1: GetModificationDelegate<T>; // ok

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