将未知类型转换为具有属性的对象



我正在尝试用TypeScript严格模式解析JSON。

基本上我有unknown类型的值。然后是

type Auth = {
accessToken: string;
};

Value很可能包含这种形状的对象,但我希望有一个在运行时和编译时都正确的转换器。

下面是我想出来的代码:
type Auth = {
accessToken: string;
};
function convert(value: unknown): Auth {
if (typeof value != "object") {
throw new Error(`Unexpected type: ${typeof value}`);
}
if (value == null) {
throw new Error("Unexpected value: null");
}
if (!("accessToken" in value)) {
throw new Error("Missing property: accessToken");
}
if (typeof value.accessToken != "string") {
throw new Error(`Unexpected type: ${typeof value.accessToken}`);
}
return value;
}

我希望这段代码完全验证未知对象的形状,但我仍然得到以下错误:

Type 'object & Record<"accessToken", unknown>' is not assignable to type 'Auth'.
Types of property 'accessToken' are incompatible.
Type 'unknown' is not assignable to type 'string'.ts(2322)

我确实理解我可以将value转换为Auth类型,但如果我将来添加新字段,但忘记向转换器添加相应的检查,这将阻止编译器帮助我,所以我想有一个不覆盖类型系统的转换器。

一种可能的解决方案利用类型谓词:

interface Auth {
accessToken: string;
};
function isAuth(value: unknown): value is Auth {
if (typeof value != "object") {
throw new Error(`Unexpected type: ${typeof value}`);
}
if (value == null) {
throw new Error("Unexpected value: null");
}
if (!("accessToken" in value)) {
throw new Error("Missing property: accessToken");
}
if (typeof value.accessToken != "string") {
throw new Error(`Unexpected type: ${typeof value.accessToken}`);
}
return true;
}

// then, say you have an unknown value and you want to check if it is an Auth
declare const x: unknown;
try {
if(isAuth(x)) {
// x type is refined as Auth in here
x.accessToken;
}
} catch(e) {
// ...
}

最新更新