如何安全地将打字稿object
转换为Record<PropertyKey, unknown>
?例如,当读取JSON时,您会得到一个any
对象,该对象实际上应该是unknown
(我认为不是为了向后兼容):
const ob = JSON.parse("{}") as unknown;
我可以使用类型断言将unknown
转换为object
:
if (typeof ob !== "object" || ob === null) {
throw new Error("Not an object");
}
// Typescript now infers the type of ob as `object`
但是,现在我应该做什么检查才能说服Typescript将其视为Record<PropertyKey, unknown>
是安全的?可能有object
个不是Record
个吗?
我确定必须要说,但是我不是在寻找ob as Record<PropertyKey, unknown>
。
答案 0 :(得分:0)
类似于注释中提到的io-ts,请查看zod以了解您的用例:https://github.com/vriad/zod/
import * as z from 'zod';
// I believe this kind of circular reference requires ts 3.7+
type JsonValue =
| { [index: string]: JsonValue }
| JsonValue[]
| boolean
| null
| number
| string;
type JsonObject = { [index: string]: JsonValue } | JsonValue[];
const valueSchema: z.ZodSchema<JsonValue> = z.lazy(() => {
return z.union([
z.record(valueSchema),
z.array(valueSchema),
z.boolean(),
z.null(),
z.number(),
z.string(),
]);
});
const objectSchema: z.ZodSchema<JsonObject> = z.lazy(() => {
return z.union([z.record(valueSchema), z.array(valueSchema)]);
});
// results in a correctly typed object, or else throws an error
objectSchema.parse(JSON.parse('whatever unknown string'));
答案 1 :(得分:0)
尽管@ {Jack Wilson}扩展了Object
界面确实有些讨厌,但它还是可以工作的。
interface Object {
[index: string]: unknown; // You can't do `[index: PropertyKey]` or `[P in PropertyKey]` for some reason.
[index: number]: unknown;
}
const ob = JSON.parse("{}") as unknown;
if (!(ob instanceof Object)) {
throw new Error("Not an object");
}
const a = ob["foo"]; // a is unknown.