1. 类型声明
- ts的类型声明包括:number、string、boolean、字面量、any、unknow、void、never、object、Array、tuple、enum
- 定义变量时不指定类型,则自动判断为any类型
- unknow类型是安全的any类型,any类型可以赋值给别的类型,unknow类型赋值给别的类型会报错
- 类型断言
let f: unknown = 'abc'; let s: string; //类型断言 s = f as string; s = <string>f;
- never类型表示没有值,即代码没有执行的结果
function fn(): never{
throw new error("报错了")
}
- 定义一个变量为对象
let a = {name: string, age?: number}
a = {name: 'xxj', age: 18}
let b = {name: string, [propName: string]: any} //即变量b里面一定有一个属性是name,别的属性尚且未知
b = {name: 'xxj', age: 18, sex: 'female'}
//[propName: string]: any 属性名是string,属性值是any
- 定义函数结构
let fn: (a: number, b: number) => number; fn = function(n1, n2): number { return n1 + n2 }
- 定义数组结构
let arr1 = string[]; arr1 = ['a', 'b', 'c']; let arr2 = Array<number>; arr2 = [1, 2, 3]
- 定义tuple元祖,即固定长度的数组
let a: [string, string] a = ['abc', 'def']
- 定义enum枚举类型
enum Gender{ female, male }; let a: {name: string, gender: Gender}; a = { name: 'xxj', gender: Gender.female };
- 定义类型的别名
type myType = 1 | 2 | 3 | 4; let a: myType
2. 类
class Person {
name: string = 'xxj';
static readonly age: number = 18
};
const person = new Person();
//实例属性只能通过实例来访问(方法也是如此)
console.log(person.name);
//用static修饰的类属性(静态属性)只能通过类来访问, readonly表示只读(方法也是如此)
console.log(Person.age);
3. 构造函数和继承
class Animal {
let name: string;
let age: number;
//构造函数在函数创建时调用
constructor(name, age){
this.name = name;
this.age = age;
}
bark(){
console.log("动物叫了")
}
}
class Dog extends Animal{
let gender: string;
constructor(name: string, age: number, gender: string){
super(name, age); //调用父类的构造函数
this.gender = gender;
}
bark(){
//super表示子类仍然调用父类的方法
//super.bark()
console.log("汪汪汪")
}
}
4. 抽象类和接口
抽象类是指在定义类之前加上abstract的修饰符,表示这个类只能用来继承,不能用来创建实例对象。接口用来定义一个类结构,定义一个类中应该包含哪些属性和方法,同时接口也可以当作类型声明来使用
interface myInter{
name: string;
sayHello(): void;
}
class MyClass implements myInter {
name: string;
constructor(name: string){
this.name = name;
}
sayHello(){
console.log("hhhh")
}
}
5. 泛型
function fn<T, K>(a: T, b: K): T{
console.log(b);
return a;
}
fn<number, string>(123, 'abc')
6. TS特殊符号
-
非空断言操作符!(后缀)
(1)忽略变量的null和undefined类型
function myFunc(maybeString: string | undefined | null) {
// Type 'string | null | undefined' is not assignable to type 'string'.
const onlyString: string = maybeString; // Error
const ignoreUndefinedAndNull: string = maybeString!; // Ok
}
(2)调用函数时忽略undefined类型
type NumGenerator = () => number;
function myFunc(numGenerator: NumGenerator | undefined) {
// Object is possibly 'undefined'.(2532)
// Cannot invoke an object which is possibly 'undefined'.(2722)
const num1 = numGenerator(); // Error
const num2 = numGenerator!(); //OK
}
(3) 确定赋值断言(即告诉ts该属性会被明确地赋值)
let x!: number;
//若写的是let x:number;则会报错:Variable 'x' is used before being assigned.
initialize();
console.log(2 * x); // Ok
function initialize() {
x = 10;
}
-
可选操作符?.
编写代码时如果遇到 null
或 undefined
就可以立即停止某些表达式的运行,立即返回undefined,支持以下语法
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
-
空值合并运算符??
(1)短路(当左侧操作符是null或者undefined时,返回右侧的操作数,否则返回左侧的操作数)
(2)与||的区别(||是只要||左侧返回的是false,包括NaN、''、0等,结果都是返回右侧的操作数,而??是只有左侧是undefined或者null的时候才会返回右侧操作数)
(3)不能与&&或者||操作符共用
-
可选属性?:
interface Person {
name: string;
age?: number;
}
let lolo: Person = {
name: "lolo"
}
工具实现:Partial<T>(快速把某个接口类型中定义的属性变成可选的)
interface PullDownRefreshConfig {
threshold: number;
stop: number;
}
/**
* type PullDownRefreshOptions = {
* threshold?: number | undefined;
* stop?: number | undefined;
* }
*/
type PullDownRefreshOptions = Partial<PullDownRefreshConfig>
Required<T>(把所有的可选的属性变成必选的)
interface PullDownRefreshConfig {
threshold: number;
stop: number;
}
type PullDownRefreshOptions = Partial<PullDownRefreshConfig>
/**
* type PullDownRefresh = {
* threshold: number;
* stop: number;
* }
*/
type PullDownRefresh = Required<Partial<PullDownRefreshConfig>>
-
运算符&
interface X {
c: string;
d: string;
}
interface Y {
c: number;
e: string
}
type XY = X & Y;
type YX = Y & X;
let p: XY;
let q: YX;
//最终c属性的类型是never
-
分隔符|
联合类型 表示取值可以为多种类型中的一种
7. TS实用工具类型
-
Partial<T>
快速把某个接口类型中定义的属性变成可选的
interface PullDownRefreshConfig {
threshold: number;
stop: number;
}
/**
* type PullDownRefreshOptions = {
* threshold?: number | undefined;
* stop?: number | undefined;
* }
*/
type PullDownRefreshOptions = Partial<PullDownRefreshConfig>
-
Pick<Type, Keys>
从基类型或接口中挑选一些属性,从而从现有类型生成新类型,Type是基类或者接口,keys是要挑选的属性
interface SuperbUser {
userId: number;
macAddress: string;
username: string;
email: string;
password: string;
firstName: string;
lastName: string;
roles: ('Admin' | 'Editor' | 'Author')[]
};
type GuestUser = Pick<SuperbUser, 'userId' | 'macAddress' | 'username'>;
//从SuperbUser中挑选出userId、macAddress、username,生成新的类型GuestUser
-
Omit<Type, Keys>
从基类或接口中排除一些属性,以生成新的类型,Type是基类或接口,Keys是要排除的属性
type SuperbUser = {
userId: number,
macAddress: string,
username: string,
email: string,
password: string,
firstName: string,
lastName: string,
roles: ('Admin' | 'Editor' | 'Author')[]
};
type Subscriber = Omit<SuperbUser, 'roles'>;