TypeScript unknown类型

TypeScript 3.0版本引入了另一种顶端类型unknown。unknown类型使用unknown关键字作为标识。示例如下:

let x: unknown;

根据顶端类型的性质,任何其他类型都能够赋值给unknown类型,该行为与any类型是一致的。

示例如下:

let x: unknown;

x = true;
x = 'hi';
x = 3.14;
x = 99999n;
x = Symbol();
x = undefined;
x = null;
x = {};
x = [];
x = function () {};

unknown类型是比any类型更安全的顶端类型,因为unknown类型只允许赋值给any类型和unknown类型,而不允许赋值给任何其他类型,该行为与any类型是不同的。示例如下:

let x: unknown;

// 正确
const a1: any = x;
const b1: unknown = x;

// 错误
const a2: boolean   = x;
const b2: string    = x;
const c2: number    = x;
const d2: bigint    = x;
const e2: symbol    = x;
const f2: undefined = x;
const g2: null      = x;

同时,在unknown类型上也不允许执行绝大部分操作。示例如下:

let x: unknown;

// 错误
x + 1;
x.foo;
x();

在程序中使用unknown类型时,我们必须将其细化为某种具体类型,否则将产生编译错误。示例如下:

function f1(message: any) {
   return message.length;
   //             ~~~~~~
   //             无编译错误
}

f1(undefined);

function f2(message: unknown) {
   return message.length;
   //             ~~~~~~
   //             编译错误!属性'length'不存在于'unknown'类型上
}

f2(undefined);

此例中,函数f1的参数message为any类型,在函数体中直接读取参数message的length属性不会产生编译错误,因为编译器不会对any类型进行任何类型检查。但如果像第7行那样在调用f1函数时传入undefined值作为实际参数,则会产生运行时的类型错误。

在函数f2中,我们将参数message的类型定义为unknown类型。这样做的话,在函数体中就不能直接读取参数message的length属性,否则将产生编译错误。在使用unknown类型的参数message时,编译器会强制我们将其细化为某种具体类型。示例如下:

function f2(message: unknown) {
   if (typeof message === 'string') {
       return message.length;
   }
}

f2(undefined);

此例中,我们使用typeof运算符去检查参数message是否为字符串,只有当message是一个字符串时,我们才会去读取其length属性。这样修改之后,既不会产生编译错误,也不会产生运行时错误。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!