在TypeScript中使用泛型扩展接口

31
我希望构建一个功能,它可以接收任何对象并返回带有几个附加属性的对象。类似于:
```javascript function addProperties(obj) { // 在此添加新属性 return obj; } ```
    //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() 

对于上述代码,TypeScript编译器返回错误,表示接口只能添加类或接口。我该如何在TypeScript中表达这个意思?
3个回答

75
你可以创建一个新的类型别名,使你的对象继承另一个对象类型的特性。我在这里找到了这段代码链接
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,
};

我已经测试过了,似乎“T”可以是接口、类和数组类型。但我无法使联合类型正常工作。
这只适用于匿名对象,不能用于实际的继承目的。
希望这有所帮助。

链接已经失效。 - Mote Zart

23

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

interface Evnt<T> {
  name: T;
}

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

我不确定您在您的情况下想要实现什么。我稍微扩展了这个示例,以便它可以编译:

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()

感谢您的时间,通过对架构进行一些小改变,您的答案确实有所帮助。 - Hamid Karimi

6
我使用以下方法解决问题:
type IModelProperty<T = Record<string, any>> = T & {
     on(): void;
     off(): void;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接