Last updated on Oct 6, 2022

any

TypeScript 为了能够表示「任意类型」,提供了一个内置类型 any,来表示任意类型。

除了显式的标记一个变量或参数为 any,在某些情况下变量/参数也会被隐式地推导为 any。比如使用 let 声明一个变量但不提供初始值,以及不为函数参数提供类型标注:

// any
let foo

// x, y 都为 any
function func(x, y) {}

以上的函数声明在 tsconfig 中启用了 noImplicitAny 时会报错。

any 类型的变量可以在声明后再次接受任意类型的值,同时可以被赋值给任意其它类型的变量:

// 被标记为 any 类型的变量可以拥有任意类型的值
let anyVar: any = 'linbudu'

anyVar = false
anyVar = 'linbudu'
anyVar = {
  site: 'juejin',
}

anyVar = () => {}

// 标记为具体类型的变量也可以接受任何 any 类型的值
const val1: string = anyVar
const val2: number = anyVar
const val3: () => {} = anyVar
const val4: {} = anyVar

同时可以在 any 类型变量上任意的进行操作(赋值、访问、方法调用等等)。

为了避免将 TypeScript 使用成 AnyScript,可以注意以下几个方面:

unknown

unknown 类型和 any 类型有些类似,一个 unknown 类型的变量可以再次赋值为任意其它类型,但只能赋值给 anyunknown 类型的变量:

let unknownVar: unknown = 'Samuel'

unknownVar = false
unknownVar = 'linbudu'
unknownVar = {
  site: 'juejin',
}
unknownVar = () => {}

const val1: string = unknownVar // Error
const val2: number = unknownVar // Error
const val3: () => {} = unknownVar // Error
const val4: {} = unknownVar // Error

const val5: any = unknownVar
const val6: unknown = unknownVar

要对 unknown 类型进行属性访问,需要进行类型断言。

let unknownVar: unknown

unknownVar.foo() // 报错:对象类型为 unknown

// 替换为
;(unknownVar as { foo: () => {} }).foo()