如何在打字稿中将类型转换为类?

时间:2020-02-10 16:22:00

标签: typescript

我有一个类Client,我想创建一个新的类UpdateClient,但是省略了类Client的一些属性。

class Client {
    constructor() {
        this.clients = '';
        this.client_secret = '';
    }
    clients: string;
    client_secret: string;
}

我希望课程UpdateClient像这样

class UpdateClient {
    constructor() {
        this.clients = '';
    }
    clients: string;
}

现在,我敢肯定Vanilla JS中几乎没有方法可以完成任务,例如遍历类client的所有可枚举属性,但我不想这么做。

我想要一个特定于打字稿的解决方案。我发现Omit类型的实用程序可以正常工作。但是,有一个小问题我无法解决。

这是整个代码段

class Client {
    constructor() {
        this.clients = '';
        this.client_secret = '';
    }
    clients: string;
    client_secret: string;
}

type T = Omit<Client, 'client_secret'>

我得到的是类型而不是类。我想以某种方式将此类型T转换为类UpdateClient并将其导出。导出的属性必须是一个类,因为使用该属性的另一个模块需要一个类。

我正在使用打字稿v3.7.5

1 个答案:

答案 0 :(得分:1)

如果您只想让UpdateClient成为创建Omit<Client, 'client_secret'>实例的类构造函数,则可以这样编写:

const UpdateClient: new () => Omit<Client, 'client_secret'> = Client;

声明的类型new () => ...的意思是“一个不带参数并生成...实例的构造函数”。该语法称为构造函数签名或"newable",并且是the static side of a class的一部分。

上面的代码将Client赋给变量UpdateClient的编译没有错误,这一事实表明编译器同意Client确实像{{ 1}}。例如,如果Omit<Client, 'client_secret'>的构造函数需要一个参数,或者如果Client不是Omit<Client, 'client_secret'>的超类型,则会出现错误:

Client

无论如何,这将起作用:

class RequiresArg {
  constructor(public clients: string) { }
}
const Oops: new () => Omit<Client, 'client_secret'> = RequiresArg; // error
// Type 'typeof RequiresArg' is not assignable to type 'new () => Pick<Client, "clients">'

class NotCompatible {
  clients?: number;
}
const StillOops: new () => Omit<Client, 'client_secret'> = NotCompatible; // error
// Type 'number | undefined' is not assignable to type 'string'.

请注意,即使编译器不知道const c = new UpdateClient(); c.clients; // okay c.client_secret; // error at compile time, although it does exist at runtime 的实例具有UpdateClient属性,但在运行时它仍只是client_secret的实例,因此该属性将在运行时肯定存在。如果这是一个问题,您可能应该做一些完全不同的事情。但是,既然您说Client对您有用,那么我想这不是问题。


好的,希望能有所帮助;祝你好运!

Playground link to code