官方文档传送门:www.typescriptlang.org/docs/
静态类型
一个变量是静态类型意味着,这个变量的类型不能修改,同时这个变量上的属性和方法也确定了
基础类型和对象类型
// 基础类型:string, number, boolean, symbol, null, undefined, void
const count: number = 123;
const myName: string = "Steven";
// 对象类型:{}, Class, function, []
class Person {}
const teacher: {
name: string;
age: number;
} = {
name: "Steven",
age: 18,
};
// 对象类型
const numbers: number[] = [1, 2, 3];
// 数组类型:表示 numbers 的类型是数组,且数组中的每一项必须是 number
const steven: Person = new Person();
// 类类型:steven 必须是 Person 类对应的对象
const getTotal: () => number = () => {
return 123;
};
// 函数类型:getTotal 是一个函数,这个函数的返回值是 number
// other case
interface Person {
name: "string";
}
const rawData = '{"name":"steven"}';
const newData: Person = JSON.parse(rawData);
let temp: number | string = 123;
temp = "456";
类型注解 type annotation
我们主动告诉 TS 变量是什么类型
let count: number;
count = 123;
类型推断 type interface
TS 会自动地去尝试分析变量的类型
如果 TS 能够自动分析变量类型,我们就什么也不需要去做了
如果 TS 无法自动分析变类型的话,我们就需要使用类型注解
函数相关类型
function add(first: number, second: number): number {
return first + second;
}
// 约束了入参的类型一般是可以推断出返回值的类型的,但防止返回值写错(如 first + second + '')最好约束返回值类型
function sayHello(): void {
console.log("hello");
}
// 约束函数返回值类型为空,即如果 return 了一个值就是错的
function errorEmitter(): never {
throw new Error();
console.log("123");
}
function loop(): never {
while (true) {}
console.log("123");
}
// 约束函数返回值类型为 never ,即函数永远不能执行完成,throw new Error() 和 while (true) {} 都造成了这个结果
function myAdd({ first, second }: { first: number; second: number }
): number {
return first + second;
}
const myTotal = myAdd({ first: 1, second: 2 });
// 解构赋值语法的类型注释
数组和元组
// 数组
const numberArr = [1, 2, 3];
const stringArr = ["1", "2"];
const undefinedArr: undefined[] = [undefined];
const arr: (number | string)[] = [1, 2, "3"];
type User = { name: string }; // type alias 类型别名
const objectArr: User[] = [{ name: "steven" }];
// 约束类型是对象数组。数组中的每一项是 User 类型,即 只有一个 name 、name 的类型是 string 的对象
class Teacher {
name: string;
age: number;
}
const objectArr1: Teacher[] = [
new Teacher(), // 可以省略
{
name: "steven",
age: 18,
},
];
// 元组 tuple
const teacherInfo: (string | number)[] = ["steven", "male", 18];
// 数组类型,类型注释为 (string | number)[],但子元素的数量、类型、顺序都没有被具体约束
const teacherInfo1: [string, string, number] = ["steven", "male", 18];
// 元组类型,同时约束了子元素,一共三项,依次为 string, string, number 类型
// 当一个数组的长度和每个元素的类型是固定的时候,可以用元组,更加确定。如读取 excel, csv 文件时
Interface
interface PersonDemo {
name: string; // PersonDemo 中必须含有 name 属性
age?: number; // PersonDemo 中的 age 属性可有可无
readonly nationality: string; // PersonDemo 中的 nationality 为只读属性
[propName: string]: any; // PersonDemo 未来可以增加其他属性
say(): string; // PersonDemo 中必须含有 say 方法这个属性,该方法返回值为 string
}
// 类型的集合可以用 interface 表示出来
// 在 TS 中,尽量用 interface 表示类型,实在不行再用 type 别名
// interface 只是 TS 帮助我们做语法校验的工具,编译后并不会变成 JS 代码
interface Person {
name: string;
age?: number;
}
const getPersonName = (person: Person): void => {
console.log(person.name);
};
const setPersonName = (person: Person, name: string): void => {
person.name = name;
};
const person = {
name: "steven",
};
getPersonName(person);
setPersonName(person, "dell");
// 当我们以字面量的形式将参数传给函数,TS 就会对该对象进行强校验
// sex 不在Person 属性中,会报错,这种情况可以在 interface 中加 [propName:string]: any
getPersonName({ name: "steven", sex: "male" });
// 如果用变量缓存,则不会那么严格,可以多传入属性
const person1 = { name: "steven", sex: "male" };
getPersonName(person1);
interface Person {
name: string;
age?: number;
say(): string;
}
class User implements Person {
name = "steven";
say() {
return "hello";
}
}
// 可以通过 implements 语法实现 class 应用 interface
// 类应用该接口时必须含有该接口的所有属性
interface Teacher extends Person {
subject: string;
}
const teacher: Teacher = {
name: "steven",
say() {
return "teacher";
},
subject: "math",
};
// interface 可以继承,继承后的类型须包含被继承类型的所有属性和自身新的属性
interface SayHi {
(word: string): string;
}
const say: SayHi = (word: string) => {
return word;
};
// 定义函数的类型声明,函数的类型叫 SayHi,该类型函数接收 string 参数,返回 string