我有一个采用泛型类型的函数,我需要确保该类型是 JSON 可序列化的(也就是只有原始属性)。
我的尝试是为 JSON 兼容类型定义一个接口,并强制我的泛型扩展此类型:
type JSONPrimitive = string | number | boolean | null
interface JSONObject {
[prop: string]: JSONPrimitive | JSONPrimitive[] | JSONObject | JSONObject[]
}
export type JSONable = JSONObject | JSONPrimitive | JSONObject[] | JSONPrimitive[]
function myFunc<T extends JSONable>(thing: T): T {
...
}
// Elsewhere
// I know that if this was defined as a `type` rather than
// an `interface` this would all work, but i need a method
// that works with arbitrary types, including external interfaces which
// are out of my control
interface SomeType {
id: string,
name: string
}
myFunc<SomeType[]>(arrayOfSomeTypes)
// The above line doesn't work, i get:
// Type 'SomeType[]' does not satisfy the constraint 'JSONable'.
// Type 'SomeType[]' is not assignable to type 'JSONObject[]'.
// Type 'SomeType' is not assignable to type 'JSONObject'.
// Index signature is missing in type 'SomeType'.ts(2344)
这里的问题似乎归结为索引签名在打字稿中的工作方式。具体来说,如果一个类型缩小了索引签名允许的可能属性,则它不能扩展具有索引签名的类型。(即SomeType不允许您任意添加foo属性,但JSONable当然可以。此问题在此现有 github 问题中有进一步描述。
所以我知道上面并没有真正起作用,但问题仍然存在,我需要一些可靠的方法来确保泛型类型是 JSON 可序列化的。有任何想法吗?
提前致谢!