typescript 在打字稿中使用泛型扩展接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26652179/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:32:50  来源:igfitidea点击:

extending interface with generic in typescript

typescript

提问by Hamid Karimi

I want to build an function which takes any object and return that object with few added properties. Something like:

我想构建一个函数,它接受任何对象并返回该对象并添加很少的属性。就像是:

    //this code doesn't work   
        function addProperties<T>(object: T): IPropertiesToAdd<T> {/*implmentions code*/};

        interface IPropertiesToAdd<T> extend T{
            on(): void;
            off(): void;
        }

//usage example
var str = new String('Hello')
addProperties(str)
str.charAt(3)
str.on() 

For the above code typescript compiler return the error that an interface can only add a class or interface, how I can express this in typescript.

对于上面的代码打字稿编译器返回一个接口只能添加一个类或接口的错误,我如何在打字稿中表达这一点。

回答by

You can create a new type aliaswhich will allow your object to inherit the features of another object type. I found this bit of code here.

您可以创建一个新的类型别名,这将允许您的对象继承另一种对象类型的功能。我在这里找到了这段代码。

type IPropertiesToAdd<T extends {}> = T & {    // '{}' can be replaced with 'any'
    on(): void
    off(): void
};

interface ISomething {
    someValue: number
}

var extendedType: IPropertiesToAdd<ISomething> = {
    on(): void {
        console.log("switched on");
    },
    off(): void {
        console.log("switched off");
    },
    someValue: 1234,
};

I've tested this, and it seems that 'T' can be an interface, class, and an array type. I couldn't get union types to work.

我对此进行了测试,似乎“T”可以是接口、类和数组类型。我无法让工会类型发挥作用。

This only works on anonymous objects, it can't be used for actual inheritance purposes.

这仅适用于匿名对象,不能用于实际继承目的。

Hope this helps.

希望这可以帮助。

回答by donnut

Interface IPropertiesToAdddefines a type variable T that is used to extend an interface named T. This is not possible. An interface can not be referred using a variable name; it must have a fixed name, e.g. Evnt:

接口IPropertiesToAdd定义了一个类型变量 T,用于扩展名为 的接口T。这不可能。不能使用变量名引用接口;它必须有一个固定的名称,例如 Evnt:

interface Evnt<T> {
  name: T;
}

interface IPropertiesToAdd<T> extends Evnt<T> {
  on(): void;
  off(): void;
}

I am not sure what you are trying to achieve in your case. I have extended the example a bit, so it compiles:

我不确定你想在你的情况下实现什么。我已经扩展了这个例子,所以它编译:

function addProperties<T>(object: Evnt<T>): IPropertiesToAdd<T> {
  /* minimum implementation to comply with interface*/
  var ext:any = {};
  ext.name = object.name
  ext.on = function() {};
  ext.off = function() {};
  return ext;
};

interface Evnt<T> {
  name: T;
}

interface IPropertiesToAdd<T> extends Evnt<T> {
  on(): void;
  off(): void;
}

//usage example
var str = {name: 'Hello'}
var evnt = addProperties(str)
evnt.charAt(3); // error because evnt is not of type 
                // `string` but `IPropertiesToAdd<string>`
evnt.on()

回答by anlijudavid

I solve the problem with:

我用以下方法解决问题:

type IModelProperty<T = Record<string, any>> = T & {
     on(): void;
     off(): void;
};