在TypeScript的构造函数中使用接口

时间:2019-10-08 21:02:56

标签: typescript

我开始用TypeScript编写我的第一个小应用程序。我正在学习有关接口以及如何在类中实现它们的知识。但是,如果我想在构造函数中使用它们呢?

假设我有一个界面:

interface WebScraper {
  url: string,
  getRawContent(): string,
}

当我使用类时,我只会编写代码

class Scraper implements WebScraper {
  //...
}

但是对于构造函数,我该怎么做呢?我将它与new关键字一起使用,因此它将返回具有特定属性的对象。如果我将接口指定为返回类型,那会正确吗?

function Scraper(): WebScraper {
  //...
}

我实际上尝试过并遇到错误

  

错误TS2355:声明类型既不是'void'也不是'any'的函数必须返回一个值。

那我该如何解决呢?

2 个答案:

答案 0 :(得分:1)

根据issue #2310,此语法已明确拒绝。拒绝的提案的语法:

interface FooInstance {
    x: number;
    y: number;
}
interface FooConstructor {
    new (x: number, y: number): FooInstance;
}
// this an error, new(x,y)=>FooInstance is not assignable to (x,y)=>void
var Foo: FooConstructor = function (x,y) {
    this.x = x;
    this.y = y;
}
var foo = new Foo(1,2);

A comment in issue #2299(产生于#2310的问题)有一种解决方法。适应您的情况:

interface WebScraper {
    url: string,
    getRawContent(): string,
}

interface WebScraperConstructor {
    new(): WebScraper;
}

const MyScraper: WebScraperConstructor =
        <WebScraperConstructor><Function>function (this: WebScraper) {
    this.url = '';
    this.getRawContent = () => '';
}

let myScraper: WebScraper = new MyScraper();

请注意,此变通办法不会通过强制转换为Function来保持类型安全,但足以将您的任意构造函数方法视为可返回您选择的值的新函数。话虽如此,根据#2310中的RyanCavanaugh的说法,这种语法绝对是不可靠的。

  

如果有什么话,我们宁愿取消使用new void函数的功能。不一致是不幸的,但我们不想添加大型安全孔,以便与我们一开始就不喜欢的刻面保持一致。

让TypeScript通过JavaScript / TypeScript class正确定义WebScraper返回值的格式正确(通过接口设置所有属性)可能是值得的。

答案 1 :(得分:0)

您的错误是因为Scraper()不返回实现WebScraper接口的对象。以下编译就可以了:

interface WebScraper {
  url: string,
  getRawContent(): string,
}

function Scraper(): WebScraper {
    return {
        url: "foobar",
        getRawContent: () => ""
    }
}

这样做:

interface WebScraper {
  url: string,
  getRawContent(): string,
}

class Scraper {
    url = "foobar";
    getRawContent() {
        return "content";
    }
}

function ScraperFactory(): WebScraper {
    return new Scraper();
}

编辑:根据评论,您需要:

interface WebScraper {
  url: string;
  getRawContent(): string;
}

function Scraper(args : WebScraper): void {
  this.url = args.url;
  this.getRawContent = args.getRawContent;
}

const scraper: WebScraper = new Scraper({url: "foo", getRawContent: () => "bar"});

值得注意的是,自new Scraper just creates a new any object and passes it to Scraper as this起,Typescript无法推断new的返回类型。 Scraperthis上运行,它不返回任何内容。这就是为什么要使用类的原因-Typescript能够推断返回对象的所需形状是什么。