291148484@163.com
1. Any 类型
2. unknown 类型
unknown
类型3. never 类型
never
类型4. void
void
运算符void
类型5. null 和 undefined
null
和 undefined
null
和 undefined
类型6. 可分配性比较
TypeScript 也有一个特殊类型 ,any只要您不希望特定值导致类型检查错误,就可以使用它。
当一个值是 typeany时,您可以访问它的任何属性(它又将是 type any),像调用函数一样调用它,将它分配给(或从)任何类型的值,或者几乎任何其他语法上的值合法的:
let obj: any = { x: 0 };
// 下面几行代码都不会抛出编译器错误。
// 使用 `any` 将禁用所有进一步的类型检查,并且假设您比TypeScript更了解环境。
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;
当你不想为了让 TypeScript 相信特定代码行没问题而写出长类型时,any 类型很有用。
noImplicitAny
选项:
当您不指定类型,并且 TypeScript 无法从上下文中推断出它时,编译器通常会默认为any.
不过,您通常希望避免这种情况,因为any没有进行类型检查。使用编译器标志noImplicitAny将任何隐式标记any为错误。
unknown
类型unknown 类型是最具有可分配性的类型之一(另一个是any),适用于在应用场景中暂不知道是什么类型,unknown 类型表示当前未知类型而在之后的操作中,一切其它类型都可以分配给 unknown 类型,这就相当于由未知到已知的过程。但是表示未知的 unknown 类型并不是表示任意类型,可以理解为相当于待定,但不意味着管它什么样子的类型都无所谓,因此唯独不能分配为 any 类型。
在开发中,当我们不确定一个变量的类型是什么类型的时候,常常声明为 any 或者 unkown,但是 any 不是类型安全的,使用 any 标识的变量将可以任意的取值赋值而不会进行任何的类型检查!
与之相反的是,unkown 必须先进行类型判断,比如使用typeof 或 instanceof 来判断类型,如果你在没有语义环境时直接使用一个 unkown 类型的变量将提示你 “unkown 类型不能 xxx”。
unknown 和 never 就像是彼此的反义词。一切都可以分配给 unknown,never 不能分配给一切。没有什么可赋给never,unknown不可赋给任何东西(any除外)。
请参考: 6. 可分配性比较
import type { ExtractPropTypes, PropType } from 'vue';type Writable = { -readonly [P in keyof T]: T[P] };
type WritableArray = T extends readonly any[] ? Writable : T;type IfNever = [T] extends [never] ? Y : N;
type IfUnknown = [unknown] extends [T] ? Y : N;/** 如果 T 为 unknown 类型,则返回 never 类型,否则返回T的类型 */
type UnknownToNever = IfUnknown;/** 提取vue setup 中单个 prop 的参数类型 */
type ExtractPropType = Valuekey: T}>
>/** 表示如果 T 是 never 返回 never 类型,否则按 { type: WritableArray, required: true} 为模板构造该单个 prop 的参数类型作为返回类型*/
type ResolvePropType = IfNevertype: WritableArrayrequired: true}>
>type PropMergeType =| IfNever, ResolvePropType, never>| UnknownToNever| UnknownToNever
注:在 vue3 框架中,提供了一个
ExtractPropTypes
类型工具,用来导出用于其setup
函数的props
类型。
any
和unknown
就可分配给它们的事物而言是相同的,不同之处在于unknown
不可分配给除 any
以外的任何事物。
请参考: 6. 可分配性比较
never
类型never 类型表示的是那些永不存在的值的类型,例如:
function error(): never {throw new "Some Error occurs.";
}
这个函数直接抛出了异常,返回类型被标记成 never
。
又例如:
function infiniteLoop(): never {while (true) {// some actions}
}
这个函数中有一个自循环,导致函数存在无法达到的终点,返回类型被标记成 never
。
见:2.2 unknown 和 never 类型的比较
void
运算符void 运算符对给定的表达式进行求值,然后返回 undefined,例如:
const output = void 1;
console.log(output);
Out[]:
undefined
void console.log('expression evaluated');
Out[]:
"expression evaluated"
void function iife() {console.log('iife is executed');
}();
Out[]:
iife is executed
void function test() {console.log('test function executed');
};
try {test();
} catch (e) {console.log('test function is not defined');
}
Out[]:
"test function is not defined"
void
类型TypeScript 中,使用同名的 void
类型表示某个值不存在。 void
不能赋值给任何对象 或 从任何对象赋值,但下列情况除外: any
、unknown
、never
、undefined
和 null
(如果 strictNullChecks
选项 为 off
。
注意:除了将 void 类型 作为函数返回值类型外,在其他地方使用void类型是无意义的。
请参阅 可分配性比较 了解详细信息)。
null
和 undefined
JavaScript 有两个原始值用于表示值不存在或未初始化的值:null
和 undefined
。
在JavaScript中,null
是一个字面量,表示缺少的标识,指示变量未指向任何对象。值 null
特指对象的值未设置,可以理解成 尚未创建的对象。
在布尔运算中被认为是 falsy
。
undefined 是全局对象的一个属性。也就是说,它是全局作用域的一个变量。undefined 的最初值就是 原始数据类型 undefined。
在函数中,如果没有使用 return
语句指定返回值,就会返回一个 undefined
值。
typeof null // "object" (因为一些以前的原因而不是'null')
typeof undefined // "undefined"
null === undefined // false
null == undefined // true
null === null // true
null == null // true
!null //true
isNaN(1 + null) // false
isNaN(1 + undefined) // true
null
和 undefined
类型TypeScript 有两个对应的 同名类型。这些类型的行为方式取决于您是否选择 strictNullChecks
选项。
当
strictNullChecks
为off
时,null
和undefined
类似于never
:可分配给大多数类型,大多数类型不可分配给它们。它们可以互相转让。
any | unknown | object | void | undefined | null | never | |
---|---|---|---|---|---|---|---|
any | - | ✓ | ✓ | ✓ | ✓ | ✓ | ✕ |
unknown | ✓ | - | ✕ | ✕ | ✕ | ✕ | ✕ |
object | ✓ | ✓ | - | ✕ | ✕ | ✕ | ✕ |
void | ✓ | ✓ | ✕ | - | ✕ | ✕ | ✕ |
undefined | ✓ | ✓ | ✓ | ✓ | - | ✓ | ✕ |
null | ✓ | ✓ | ✓ | ✓ | ✓ | - | ✕ |
never | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | - |