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

Kar*_*han 1 typescript

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

class Client {
    constructor() {
        this.clients = '';
        this.client_secret = '';
    }
    clients: string;
    client_secret: string;
}
Run Code Online (Sandbox Code Playgroud)

我希望课堂UpdateClient是这样的

class UpdateClient {
    constructor() {
        this.clients = '';
    }
    clients: string;
}
Run Code Online (Sandbox Code Playgroud)

现在,我确信在普通 JS 中我可以通过几种方法来完成任务,比如迭代 class 的所有可枚举属性client,但我不想这样做。

我想要一个特定于打字稿的解决方案。我发现Omit类型实用程序并且它按预期工作。但是,有一个小问题我无法解决。

这是整个代码片段

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

type T = Omit<Client, 'client_secret'>
Run Code Online (Sandbox Code Playgroud)

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

我正在使用打字稿v3.7.5

jca*_*alz 5

如果您想要的只是UpdateClient一个创建 实例的类构造函数Omit<Client, 'client_secret'>,您可以这样编写:

const UpdateClient: new () => Omit<Client, 'client_secret'> = Client;
Run Code Online (Sandbox Code Playgroud)

声明的类型new () => ...意味着“一个不带参数并生成...实例的构造函数”。该语法称为构造函数签名或new能够”,并且是类的静态部分的一部分。

上面的代码分配Client给变量,UpdateClient编译时没有错误,这一事实表明编译器同意它的Client行为就像 的无参数构造函数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'.
Run Code Online (Sandbox Code Playgroud)

不管怎样,这样就可以了:

const c = new UpdateClient();
c.clients; // okay
c.client_secret; // error at compile time, although it does exist at runtime
Run Code Online (Sandbox Code Playgroud)

请注意,即使UpdateClient编译器不知道 's 实例具有client_secret属性,它仍然只是运行时的实例Client,因此该属性在运行时肯定存在。如果这是一个问题,你可能应该做一些完全不同的事情。但既然你说Omit<...>适合你,我想这不是问题。


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

Playground 代码链接