1、函数声明、定义、使用
函数声明:制定函数的参数和返回值类型
函数实现:函数具体的实现,参数可少于等于函数的定义。函数实现参数TS会根据函数的声明进行推断
函数调用:函数的调用参数必须要和函数的声明一致,不然会报错
2、索引签名
TS支持字符串和数字索引,可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型
3、 强制类型转换
-
as
-
利用泛型
interface Square {
color: string;
sideLength: number
}
let square = <Square>{}; // 强制类型转换,并进行初始化
square.color = "blue";
square.sideLength = 10;
4、类
-
访问修饰符(都是针对实例属性)
-
private:私有,只能在本类和实例中被访问
-
protect:受保护,在本类以及其派生类中可被访问
-
public:不受限制
-
-
静态属性、实例属性
-
实例属性需要在被实例化时进行初始化,静态属性挂在类上,类存在,静态属性就存在。
-
实例属性、方法只能实例方法中访问,静态属性和方法可以在实例方法和静态方法中被访问
-
5、类型保护
-
交叉类型
obj: A & B & C,obj必须包含有A、B、C中的所有属性,均可直接访问
2. 联合类型
obj:A | B,obj是A或者是B类型,obj中一定包含A和B共有的属性,但是非公有属性不能直接访问,直接访问会报错,所以引出下面的类型保护
3. 类型保护
联合类型中非公有的属性不可直接访问,编译不通过
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// ...
}
let pet = getSmallPet();
// 每一个成员访问都会报错
if (pet.swim) {
pet.swim();
}
else if (pet.fly) {
pet.fly();
}
可通过已下几种方式进行处理
-
类型断言
let pet = getSmallPet(); if ((<Fish>pet).swim) { (<Fish>pet).swim(); } else { (<Bird>pet).fly(); }
-
户自定义的类型保护
function isFish(pet: Fish | Bird): pet is Fish { return (<Fish>pet).swim !== undefined; } // 'swim' 和 'fly' 调用都没有问题了 if (isFish(pet)) { pet.swim(); } else { pet.fly(); }
-
typeof类型保护
function a(padding: string | number): string | number { if (typeof padding === 'number') { } else { } }
-
instanceof类型保护
与typeof类型保护类似
6、null、undefined
-
null、undefine的是其他类型的子集,当你声明一个变量时,它会自动地包含 null或 undefined;使用--strictNullChecks,将不允许将二者赋值给其他类型,除非对变量进行联合类型声明
let s = "foo";
s = null; // 错误, 'null'不能赋值给'string'
let sn: string | null = "bar";
sn = null; // 可以
sn = undefined; // error, 'undefined'不能赋值给'string | null'
-
null 和undefined属于不同类型
-
使用了 --strictNullChecks,可选参数会被自动地加上 | undefined
function f(x: number, y?: number) {
return x + (y || 0);
}
f(1, 2);
f(1);
f(1, undefined);
f(1, null); // error
-
手动排除null/undefined
可在变量后面添加'!'
function postfix(name: string | null) {
return name!.charAt(0) + '. the '; // 排除null和undefined
}
7、特殊类型demo
-
Exclude<T, U> -- 从T中剔除可以赋值给U的类型。
-
Extract<T, U> -- 提取T中可以赋值给U的类型。
-
NonNullable<T> -- 从T中剔除null和undefined。
-
ReturnType<T> -- 获取函数返回值类型。
-
InstanceType<T> -- 获取构造函数类型的实例类型。
-
Pick<T, K> -- 获取T中的K属性,属性值类型不变 【同态】
interface Person {
name: string;
age?: number;
}
type person5 = Pick<Person, "name">;
// person5 === {name: string}
-
Partial<T> -- T中属性变为可选属性,属性值类型不变【同态】
-
Readonly<T> -- T中属性变为只读属性,属性值类型不变【同态】
-
Record<K, T> 拷贝K中属性,新定义属性值类型为T【不同态】, https://www.leevii.com/2018/10/record-in-typescript.html
【不同态:表示必须输入属性值类型,拷贝属性定义新类型】
8、命令空间
-
命名空间区分文件但是隶属同一个命名空间时,可以通过<reference path="Validation.ts" />进行关联
-
文件输出可以按照顺序输出到一个文件,或者是分别输出,但是均需引用
9、模块查找
-
相对模块:本地模块,通过相对路径引用,如:import * as from './hhh.js'
-
非相对模块:npm模块,通过模块名引用,如 import moment from 'moment'
a. 模块查找路径设置
"baseUrl": "./", /* Base directory to resolve non-absolute module names. */
"paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"@assets/*": ["src/assets/*"],
"react-native": ["node_modules/@mrn/react-native"],
"@mfe/react-native-vector-icons/FontAwesome": ["node_modules/@types/react-native-vector-icons/FontAwesome"],
"moment/min/moment.min.js": ["node_modules/moment"]
},
-
设置baseUrl来告诉编译器到哪里去查找模块。 所有非相对模块导入都会被当做相对于 baseUrl。注意相对模块的导入不会被设置的baseUrl所影响,因为它们总是相对于导入它们的文件
baseUrl的值由以下两者之一决定:
-
命令行中baseUrl的值(如果给定的路径是相对的,那么将相对于当前路径进行计算)
-
‘tsconfig.json’里的baseUrl属性(如果给定的路径是相对的,那么将相对于‘tsconfig.json’路径进行计算)
-
-
设置path相当于配置地址别名,react-native本来需要通过‘@mrn/react-native’形式引用,现在可以直接通过'react-native'形式引用
b. 利用rootDirs指定虚拟目录
{
"compilerOptions": {
"rootDirs": [
"src/views",
"generated/templates/views"
]
}
}
构建过程中会将上面两个目录下的文件拷贝到一个文件目录下,这样在src/views目录下的文件中使用template/views中的文件时,可以通过'./template.js'形式访问