2017-01-26 101 views
2

它可以創建一個DeepReadonly類型是這樣的:DeepReadonly對象打字稿

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

interface A { 
    B: { C: number; }; 
    D: { E: number; }[]; 
} 

const myDeepReadonlyObject: DeepReadonly<A> = { 
    B: { C: 1 }, 
    D: [ { E: 2 } ], 
} 

myDeepReadonlyObject.B = { C: 2 }; // error :) 
myDeepReadonlyObject.B.C = 2; // error :) 

這是偉大的。 BB.C都是隻讀的。當我嘗試修改D但是......

// I'd like this to be an error 
myDeepReadonlyObject.D[0] = { E: 3 }; // no error :(

我應該怎麼寫DeepReadonly使嵌套數組是隻讀的呢?

+0

我沒有收到'console.log(myDeepReadonlyObject.D [0])的錯誤;'您使用哪種版本的打字稿? –

+0

我在我的tsconfig中設置了「noImplicitAny」標誌。但問題仍然存在。我已經更新它更清楚。謝謝。 –

回答

1

你可以有一個只讀數組:

interface ReadonlyArray<T> extends Array<T> { 
    readonly [n: number]: T; 
} 
let a = [] as ReadonlyArray<string>; 
a[0] = "moo"; // error: Index signature in type 'ReadonlyArray<string>' only permits reading 

但你不能用你的解決方案使用它:

interface A { 
    B: { C: number; }; 
    D: ReadonlyArray<{ E: number; }>; 
} 

myDeepReadonlyObject.D[0] = { E: 3 }; // still fine 

類型的DDeepReadonly<ReadonlyArray<{ E: number; }>>,它不會允許ReadonlyArray去踢

我懷疑你會設法使它對數組中的對象有效,你可以只對數組進行深層讀取如果你想要一個通用的接口/類型而不是特定的接口或對象。
例如,這將很好地工作:

interface A { 
    readonly B: { readonly C: number; }; 
    D: ReadonlyArray<{ E: number; }>; 
} 

const myDeepReadonlyObject = { 
    B: { C: 1 }, 
    D: [{ E: 2 }], 
} as A; 

myDeepReadonlyObject.B = { C: 2 }; // error 
myDeepReadonlyObject.B.C = 2; // error 
myDeepReadonlyObject1.D[0] = { E: 3 }; // error 

但它有一個特定的接口,它(A),而不是通用的一個DeepReadonly

另一種選擇是使用Immutable.js,它內置了一個內置定義文件,使用起來非常簡單。

+0

謝謝。這是一種真正的恥辱,這似乎還不可能。任何人有任何想法,如果它在工作中? –