const
getUser
= (
user: User
) => {
console
.
log
(user.
name
, user.
age
.
toString
())
age 是可选的,但是在 console.log 中调用了 toString 方法。
ts: Object is possibly 'undefined'.ts(2532) 我们可以使用
?.
来解决这个🐛,严格检查
console.log(user.name, user.age?.toString())
boolean 布尔类型
string 字符串类型
void/null/undefined 三种空类型
any/any[]
类型
tuple 元祖类型
never/unknown
函数/构造函数字面量类型
函数调用类型
构造函数签名
按级别划分类型
顶级类型 top type
any/unknown. 包含所有类型的集合。
底部类型 bottom type
never 空集合
从类型 type
引出接口 interface
在 TypeScript 中,使用 type 关键字,定义类型别名
type User = number | string;
⚠️:别名 type 一旦定义定义就不能扩展自己
,只能用 type
定一个其他的类型。基于别名 type 自生不可扩展,引出 接口 interface 的概念就很合适了。
interface Global {
api1: number
我们想要扩展 Global 接口,就可以直接重新定义(重新定义不是简单的覆盖行为)
interface Global {
api2: number
api2接口属性是补充在 Global 属性上面的,而不是覆盖之前定义的 api1。
TypeScript 对象类型 Object Types
对象类型应该是我们最常用的复合类型在之一了。
定义对象类型的方式:
interface
他们的最主要的区别之一就是:能不能不产生新的类型
的基础上扩展自己。
可选/只读的类型属性
可选: ?.<your option>
只读: readonly <you option>
有时候,我们不确定属性的名称,此时我们就可以定义索引类型
interface User {
[index: string]: any
index
表示索引,索引的类型是 string,属性对应的类型是 any
interface 的类型扩展
重新定义接口,然后补充新的属性,不产生
一个新的接口
使用 extend 关键字补充,产生
一个新的接口
type 的类型补充
使用 |
联合类型,进行扩展,产生
一个新的类型。
两个类型交叉,将两个不同类型组合成一个新的类型没有重复
的新的类型
type A = {
name: string
age: number
type B = {
age: number
sex: string
const C: A & B = {
name: 'sdfd',
age: 123,
sex: 'male'
const D: A | B = {
name: 'sdf',
age: 123
重要关键字
extends 赋值(也可以叫分配) 。 广泛应用于条件类型,是高级类型的基石。
keyof 获取索引值,并组合成新的索引值联合类型。
范型,有一个广义上的类型,但是这个类型具体还不确定,由于不确定所有可以是多种类型。是一对多的关系。常使用 T, U 表示范型,常用于函数参数的约束。
function fn<T>(a: T) {};
T 就范型类型,范型类型确定后,fn 函数参数的类型就确定了。 T 可以对应多个类型。
开始可以粗糙的理解为: 数学中的并集。联合类型使用 |
操作符来联合类型
type A = string | number;
注意,黏合类型在切换类型的时候,整个值切换
type B = boolean | {z: string};
let binst: B = {z: 123};
binst = false;
开始可以粗糙的理解为: 数学中的交集。联合类型使用 &
操作符来交叉类型
type X = string & number;
所以交叉类型常用于一下相对复杂点的类型.
type C = string | number;
type D = string | Function
type CxD = C & D;
const h: CxD = 'this is cxd type';
const hF: CxD = 12312;
const gF: CxD = () => {};
类型中也有索引操作,获取索引,设置索引
keyof 获取类型索引
使用 []
来定义索引类型和索引值类型
type INN = {
a: string;
b: string;
const kea: keyof INN = "a";
const keb: keyof INN = "b";
const kec: keyof INN = "c";
type INN = {
a: string;
b: string;
[index: string]: any;
const kea: keyof INN = "a";
const keb: keyof INN = "b";
const kec: keyof INN = "c";
与 js 的三元表达式相似。常与 extends 关键字以及范型配合使用形成高级类型。
T extends U ? X : Y;
理解: T 赋值
给 U 之后正确吗?正确取 X 类型,否则取 Y 类型。
因为 extends 关键字是 TypeScript 高级类型的基石。所以下面会啰嗦一下,用 js 类型打好基础:
type StrT = "abc" extends string ? "StrTrue" : "StrFalse";
type StrF = "abc" extends unknown ? "StrTrue" : "StrFalse";
type BoolT = true extends boolean ? "BoolTrue" : "BoolFalse";
type BoolF = true extends unknown ? "BoolTrue" : "BoolFalse";
type NumT = 123 extends number ? "NumTrue" : "NumFalse";
type NumF = 123 extends unknown ? "NumTrue" : "NumFalse";
type NullT = null extends null ? "NullTrue" : "NullFalse";
type NullT1 = null extends unknown ? "NullTrue" : "NullFalse";
type NullT2 = null extends any ? "NullTrue" : "NullFalse";
type NullT3 = null extends void ? "NullTrue" : "NullFalse";
type NullT4 = null extends boolean ? "NullTrue" : "NullFalse";
type ObjT = {} extends Object ? "ObjTrue" : "ObjFalse";
type ObjT1 = {} extends unknown ? "ObjTrue" : "ObjFalse";
type ObjT2 = {} extends any ? "ObjTrue" : "ObjFalse";
type ObjT3 = {} extends void ? "ObjTrue" : "ObjFalse";
type ObjT4 = {} extends boolean ? "ObjTrue" : "ObjFalse";
type ObjT5 = {} extends null ? "ObjTrue" : "ObjFalse";
最佳的 TypeScript Null 类型检查实践