TypeScript 基础类型
目录:
- 概述
- 基本数据类型
- any 类型
- 数组 Array
- 元组 Tuples
- 枚举 Enum
- 函数 Function
- 对象 Object
- 类型推断
概述
在 TypeScript 中 开发者可以通过类型注释对变量 参数 返回值的类型进行标注
JavaScript | TypeScript |
---|---|
number | any |
string | unknow |
boolean | never |
null | enum |
undefined | tuple |
object |
基本数据类型
// 数值类型
let apples: number = 5;
// 字符串类型
let speed: string = "fast";
// 布尔值类型
let hasName: boolean = true;
// TS2322: Type 'string' is not assignable to type 'number'
// 类型 'string' 不能分配给类型为 'number'
apples = "5"; // ❎
// TS2322: Type 'number' is not assignable to type 'string'.
// 类型 'number' 不能分配给类型 'string'
speed = 120; // ❎
// TS2322: Type 'string' is not assignable to type 'boolean'.
// 类型 'string' 不能分类给类型 'boolean'
hasName = "yes"; // ❎
any 类型
// any 类型
// 变量中可以存储任何数据类型的值
let anything: any = "Hello TypeScript";
anything = true; // ✅
anything = 3.14; // ✅
anything = function () {}; // ✅
anything = null; // ✅
数组 Array
// 在没有为数组显示标注类型时 变量的初始值又是一个空数组
// 此时数组中可以存储任何类型的值
// 虽然写法正确 但丢失了 TypeScript 类型检查功能
// let colors = any[];
let colors = [];
colors[0] = 1; // ✅
colors[1] = "Hello"; // ✅
// 字符串数组
let colors: string[] = ["red", "green", "blue"];
// 数值数组
let numbers: number[] = [100, 200, 300];
// 布尔数组
let bools: boolean[] = [true, true, false];
// 二维数组
const carMakers: string[][] = [["宝马", "比亚迪"]];
// item: string
colors.forEach((item) => {});
// let colors: string[]
colors[0];
元组 Tuples
在 employee 数组中我们约定在数组中下标为0的位置存储员工姓名,在下标为1的位置存储员工的年龄
let employee = ["张三", 20];
employee[0] = 30;
employee[1] = "李四";
以上代码存在的问题是 employee 数组没有被类型系统约束,没有约束每个数组元素对应的类型,导致在错误位置修改元素值时没有错误提示。
元组是 TypeScript 引入的一种新数据类型,它像数组一样工作但是有一些额外的限制:元组中元素个数是固定,元组中元素类型已知。
元组用来存储一些以特定顺序出现且相关关联的数据,通过元组可以约束元素个数及元素类型。
const employee: [string, number] = ["张三", 20];
// 不能将类型"number"分配给类型"string"
employee[0] = 30;
// 不能将类型"string"分配给类型"number"
employee[1] = "李四";
// 使用元组存储 RGB 颜色值及透明度
var bgColor: [number, number, number, number] = [0, 255, 255, 0.5];
// 创建元组数组(二维数组)
var employees: [number, string][] = [
[1, "Steve"],
[2, "Tom"],
];
枚举 Enum
枚举用于存储一组密切相关且有限的值,可以提升代码的可读性,可以限定值的范围,比如比赛结果,考试成绩,颜色种类,性别等等
enum Sizes {
Small, // Small = 0
Medium, // Medium = 1
Large, // Large = 2
}
console.log(Sizes.Small); // 0
enum Sizes {
Small = 1,
Medium,
Large,
}
console.log(Sizes.Small)
// 如果枚举值为非数值,每个属性都必须进行初始化
enum Sizes {
Small = "s",
Medium = "m",
Large = "l",
}
console.log(Sizes.Small);
// 枚举被编译为了 JavaScript 中的对象
var Sizes;
(function (Sizes) {
Sizes["Small"] = "s";
Sizes["Medium"] = "m";
Sizes["Large"] = "l";
})(Sizes || (Sizes = {}));
// 在声明枚举类型时 如果使用 const 关键字 TypeScript 编译器将输出更加简洁的代码
const enum Sizes {
Small = "s",
Medium = "m",
Large = "l",
}
let selected = Sizes.Large;
console.log(selected);
// 枚举使用示例
enum Sizes {
Small = "s",
Medium = "m",
Large = "l",
}
let selected: Sizes = Sizes.Small;
function updateSize(size: Sizes) {
selected = size;
}
updateSize(Sizes.Large);
场景 | 使用/不使用 |
---|---|
消息的阅读状态 | YES |
从1750年到现在的年份列表 | NO |
菜单中饮料的种类 | YES |
文章列表的所有标题 | NO |
服务器端的电影分类 | NO |
颜色选择器中的颜色 | YES |
函数 Function
通过类型注释可以显示设置要接收的参数的类型 函数要返回的值得类型
function add(a: number, b: number): number {
return a + b;
}
cinst add = (a: number, b: number): number => {
return a + b;
};
sum(10, "20")
let logNumber: (n: number) => void;
logNumber = (m: number): void => {
console.log(m);
}
如果函数没有返回值 可以使用 void 进行标注
function log(): void {}
TypeScripe 编译器会检查实参的类型以及参数数量是否正确
function sum(a: number, b: number): number {
return a + b;
}
// TS2554: Expected 2 arguments, but got 3.
sum(10, 20, 30);
TypeScript 编译器会检测函数是否拥有正确的返回值。
function sum(a: number): number {
if (a > 10) return a + 20;
}
TypeScript 编译器会检测函数内部没有使用的变量
function log() {
// 没使用的 局部变量 x
// 移除没使用的 局部变量 "x"
let x;
}
通过 ? 的方式设置可选参数, 它的类型是要么是它原本的类型要么是 undefined。
// c?: number | undefined
function sum(a: number, b: number, c?: number): number {
if (typeof c !== "undefined") {
return a + b + c;
}
return a + b;
}
sum(10, 20);
通过参数默认值的方式设置可选参数,它的类型就是原本的类型。
// c?: number
function sum(a: number, b: number, c: number = 0): number {
return a + b + c;
}
sum(10, 20);
在定义函数时 如果形参被定义为解构语法 使用下面的方式为函数形参设置类型
const logWeather = ({data, weather}: {date: Date; weather: string}) => {
console.log(data, weather);
};
const today = {
data: new Date(),
weather: "sunny"
};
logWeather(today);
const profile = {
age: 20,
coords: {
lat: 0,
lng: 15,
},
};
const { age }: {age: number} = profile;
const {
coords: {lat, lng},
}: {coords: {lat: number; lng: number}} = profile;
对象 Object
// 对象字面量
let point: {x: number; y: number} = {x: 100, y: 200};
let employee: {readonly id: number} = {id: 1};
let people = {};
let student: {age?: number} = {}
student.age = 20;
// 内置对象 类本身可以作为类实例的类型
let date: Date = new Date();
// 自定义类
// 类可以作为类实例的类型
class Car {}
let car: Car = new Car();
类型推断
TypeScript 编译器能根据一些简单的规则推断变量的类型 在没有显示设置变量类型的情况下 编译器把变量的类型作为变量的类型
let apples = 5;
let speed = "fast";
let hasName = true;
let colors = ["red", "green", "blue"];
let numbers = [100, 200, 300];
let bools = [true, true, false];
let anything = [];
let point = {x: 100, y: 200};
TypeScript 编译器会试图推断函数返回值的类型
注意:使用函数返回值类型推断时 在编写函数内部代码时就失去了类型检测功能 所以函数返回值类型推荐明确指定 如果函数的返回值是 undefined 可以指定函数的返回值为 void
const add = (a: number, b: number) => {
return a+b;
};
const add = (a: number, b: string) => {
return a + b;
};
const add = () => {
return "a";
};
const find = (name: string) => {
if (name) {
return name;
}else {
return false;
}
};
在TypeScript 编译器可以推断出变量类型的情况下 开发者不需要显示编写类型 也就是说只有在 TypeScript 不能正确推断变量类型的情况下开发者需要编写类型 那么在那些情况下 编译器不能正确推断出变量的类型呐?
1 如果在变量声明后没有被立即初始化,TypeScript 编译器不能正确的推断出它的类型。
let anything;
anything = 12;
anything = "hello";
anything = true
let colors = ["red", "green", "blue"];
let foundColor;
for (let i = 0; i < colors.length; i++) {
if(colors[i] === "green") {
foundColor = trun;
}
}
2 当调用的函数返回值为 Any 类型时 我们应该使用类型 显示他的类型
let json = `{"name": "张三"}`;
let person = JSON.parse(json);
3 当变量可能有多个类型的值时
// 需求: 在数组中找 大于0 的数值 给变量 target 如果没有找到 false 赋值给变量 target
let number = [-10, -1, 20];
let target = false;
for(let i = 0; i < numbers.length; i ++) {
if (numbers[i] > 0) {
// 不能把类型 number 分配给类型 boolean
target = numbers[i];
}
}
let target: boolean | number = false;
4 函数的参数必须设置类型 TypeScript 并不能推断函数参数的类型
function sum(a, b) {};