typescript - 如何將類別導出為唯讀,但允許內部修改?
由於我的類別有非同步初始化過程。我必須定義一個只讀公共屬性,但在內部修改它,比如
declare function asyncAppMap(target: string): Promise<Window>
class FrameInternal {
public readonly content: Window | null = null
constructor(target: string) {
asyncAppMap(target).then(app => {
// Not possible currently.
// this.content = app
})
}
}
我正在尋找一些可重複使用的工具,例如:
class FrameInternal{}
// Then all members of Frame becomes readonly
export const Frame: ReadonlyClass<FrameInternal> = FrameInternal
答案#1
根據你的具體需求,你可以使用類似這樣的東西:
type ReadonlyClass<T extends new (...args: any) => any> =
T extends new (...args: infer A) => infer R ?
new (...args: A) => { readonly [K in keyof R]: R[K] } : never;
類型 ReadonlyClass 將一個建構子類型轉換為新的建構子類型,該類型生成的實例類型的所有屬性都被標記為 readonly。
當你導出一個類別建構函數時,你可能也想導出一個同名的類型,對應於實例類型。當你使用 class Foo {} 表示法時,這會自動發生(Foo 既被引入為類別建構函數的名稱,也被引入為類別實例類型的名稱):
export const Frame: ReadonlyClass<typeof FrameInternal> = FrameInternal;
export type Frame = InstanceType<typeof Frame>;
當你檢查它時,看起來像這樣:
/*
const Frame: new (target: string) => {
readonly content: Window | null;
}
type Frame = {
readonly content: Window | null;
}
*/
至少在你上面展示的範例情況下,這應該可行:
const f = new Frame("z");
f.content = null; // error, can't assign to read only
function acceptFrame(f: Frame) {
f.content = null; // error here too
}
好的,希望那有幫助;祝你好運!
程式碼連結
