首页 > 解决方案 > TypeScript:创建具有可写属性的子类

问题描述

我正在尝试定义一种类型T,其中 的所有属性T都是非只读(可写),但仍可分配给T. 但是,当有私有/受保护的属性时,这似乎不起作用T

type Writable<T> = {
    -readonly [P in keyof T]: T[P];
}

class HttpClient {
    private handler: any;

    readonly foo: any;

    get(): void {
      // ...
    }
}

 // Error: property 'handler' is missing in type 'Writable<HttpClient>'
 // but required in 'HttpClient'
const httpClient: HttpClient = {} as Writable<HttpClient>; 

有没有办法让这个工作?

标签: typescript

解决方案


映射类型,例如Writable不能映射私有字段(它们不是 keyof返回内容的一部分)。这是设计使然,毕竟不应从外部访问私有字段。

此外,如果一个类有一个private字段,则对象文字(即使它包含私有字段)根据定义不能满足该类的类型。


 // Property 'handler' is private in type 'HttpClient' but not in type '{ handler: string; foo: string; get(): void; }'.
const httpClient: HttpClient = { // not assignable
  handler: "",
  foo: "",
  get () {}
}

即使是另一个具有同名私有字段的类也不能满足原始类。

// Type '(Anonymous class)' is not assignable to type 'HttpClient'.
//   Types have separate declarations of a private property 'handler'.
const httpClient2: HttpClient = new class { // not assignable
  private handler: any
  foo: any
  get () {}
} 

使这项工作的唯一方法是私有字段是可选的:

class HttpClient {
    private handler?: any;

    readonly foo: any;

    get(): void {
      // ...
    }
}

const httpClient: HttpClient = {
  foo: "",
  get () {}
}
console.log(httpClient instanceof HttpClient) // false 

此外,由于具有可写属性的对象可以分配给具有readonly属性的引用,因此根本不需要Writable

注意:即使您可以将对象文字分配给类,它也不会是该类的实例,因此httpClient instanceof HttpClient是错误的。


推荐阅读