在 TypeScript 中扩展数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12802383/
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-11 00:51:43  来源:igfitidea点击:

Extending Array in TypeScript

typescript

提问by Francois Vanderseypen

How to add a method to a base type, say Array? In the global module this will be recognized

如何将方法添加到基本类型,比如 Array?在全局模块中,这将被识别

interface Array {
   remove(o): Array;
}

but where to put the actual implementation?

但是在哪里放置实际的实现呢?

回答by Fenton

You can use the prototype to extend Array:

您可以使用原型来扩展 Array:

interface Array<T> {
    remove(o: T): Array<T>;
}

Array.prototype.remove = function (o) {
    // code to remove "o"
    return this;
}

If you are within a module, you will need to make it clear that you are referring to the global Array<T>, not creating a local Array<T>interface within your module:

如果您在一个模块中,则需要明确表示您指的是 global Array<T>,而不是Array<T>在您的模块中创建本地接口:

declare global {
    interface Array<T> {
        remove(o: T): Array<T>;
    }
}

回答by Rikki Gibson

declare globalseems to be the ticket as of TypeScript 2.1. Note that Array.prototypeis of type any[], so if you want to have your function implementation checked for consistency, best to add a generic type parameter yourself.

declare global似乎是 TypeScript 2.1 的票。请注意,它Array.prototype是 type any[],因此如果要检查函数实现的一致性,最好自己添加一个泛型类型参数。

declare global {
  interface Array<T> {
    remove(elem: T): Array<T>;
  }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(this: T[], elem: T): T[] {
    return this.filter(e => e !== elem);
  }
}

回答by GAF

Adding to Rikki Gibson's answer,

添加到 Rikki Gibson 的回答中,

export{}
declare global {
    interface Array<T> {
        remove(elem: T): Array<T>;
    }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(elem: T): T[] {
      return this.filter(e => e !== elem);
  }
}

Without the export{} TS error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."

如果没有 export{} TS 错误“全局范围的增强只能直接嵌套在外部模块或环境模块声明中。”

回答by Alex

From TypeScript 1.6, you can "natively" extend arbitrary expressions like inbuilt types.

从 TypeScript 1.6 开始,您可以“本地”扩展任意表达式,例如内置类型。

What's new in TypeScript:

TypeScript 的新特性

TypeScript 1.6 adds support for classes extending arbitrary expression that computes a constructor function. This means that built-in types can now be extended in class declarations.

The extends clause of a class previously required a type reference to be specified. It now accepts an expression optionally followed by a type argument list. The type of the expression must be a constructor function type with at least one construct signature that has the same number of type parameters as the number of type arguments specified in the extends clause. The return type of the matching construct signature(s) is the base type from which the class instance type inherits. Effectively, this allows both real classes and "class-like" expressions to be specified in the extends clause.

TypeScript 1.6 添加了对扩展计算构造函数的任意表达式的类的支持。这意味着现在可以在类声明中扩展内置类型。

类的 extends 子句以前需要指定类型引用。它现在接受一个可选的表达式,后跟一个类型参数列表。表达式的类型必须是具有至少一个构造签名的构造函数类型,该构造签名的类型参数数量与 extends 子句中指定的类型参数数量相同。匹配构造签名的返回类型是类实例类型继承的基类型。实际上,这允许在 extends 子句中指定真实的类和“类类”表达式。

// Extend built-in types

class MyArray extends Array<number> { }
class MyError extends Error { }

// Extend computed base class

class ThingA {
    getGreeting() { return "Hello from A"; }
}

class ThingB {
    getGreeting() { return "Hello from B"; }
}

interface Greeter {
    getGreeting(): string;
}

interface GreeterConstructor {
    new (): Greeter;
}

function getGreeterBase(): GreeterConstructor {
    return Math.random() >= 0.5 ? ThingA : ThingB;
}

class Test extends getGreeterBase() {
    sayHello() {
        console.log(this.getGreeting());
    }
}

回答by chenxu

class MyArray<T> extends Array<T> {
    remove: (elem: T) => Array<T> = function(elem: T) {
        return this.filter(e => e !== elem);
    }
}
let myArr = new MyArray<string>();
myArr.remove("some");

this works for me with typescript v2.2.1!

这适用于打字稿 v2.2.1!

回答by Joerg

I just had to do the same and created a generic function that includes a mapping.

我只需要做同样的事情并创建一个包含映射的通用函数。

getDistinctValuesFromArray<T,R>(array: T[], mapping: (values: T) => R): R[] {
    return Array.from([...new Set(array.map(mapping))]);
}

You can call it then like: getDistinctValuesFromArray<ArrayType, ElementType>(yourArray, a => a.elem)To make it concrete I like to add the specific types like ArrayType and ElementType. Those you need to replace for sure with your types.

你可以这样称呼它: getDistinctValuesFromArray<ArrayType, ElementType>(yourArray, a => a.elem)为了使它具体,我喜欢添加特定类型,如 ArrayType 和 ElementType。那些你肯定需要用你的类型替换的。