ts基础
基本数据类型
// 字符串类型
const name: string = 'zhangsan'
// 数值类型
const age: number = 15
const hex: number = 0xff
// 布尔类型
const adult: boolean = false
const graduated: boolean = 0any类型
any,可以是如何类型,不推荐使用
let anyData: any = 123
anyData = 'zhangsan'
anyData = trueunknown类型
unkonwn,表示未知类型,会自动推导第一次赋值的类型
let unkonwnData: unkonwn
unkonwnData = 123
unkonwnData = 'zhangsan' // 报错: 类型“string”的参数不能赋给类型“number”的参数void类型
void,表示空类型,表示没有返回值
function print(): void {
console.log('hello world')
}never类型
never,表示永远不会有返回的类型
- 如抛出异常
- 死循环
function error(message: string): never {
throw new Error(message)
}
function infiniteLoop(): never {
while (true) {
}
}使用场景
它是所有类型的子类型,但没有任何类型是它的子类型(除了自身),主要用于:
- 永远不结束的函数:如抛错函数、无限循环函数;
- 类型收窄到不存在:结合条件判断,标记「不可能触发的分支」;
- 排除联合类型的所有可能:实现严格的类型穷尽检查。
<script setup lang="ts">
import {ref} from 'vue';
const number = ref(0);
// 字面类型
type Fruit = "apple" | "banana" | "orange";
function getFruitPrice(fruit: Fruit): number {
switch (fruit) {
case "apple":
return number.value = 5;
case "banana":
return number.value = 3;
case "orange":
return number.value = 4;
default:
const _exhaustiveCheck: never = fruit;
throw new Error(`未知水果:${_exhaustiveCheck}`);
}
}
</script>
<template>
{{ number }}
<button @click="getFruitPrice('apple')">苹果</button>
<button @click="getFruitPrice('banana')">香蕉</button>
<button @click="getFruitPrice('watermelon')">西瓜</button>
</template>对于never和void类型
- 两者都可表示空类型,但never比void更严格,never表示永远不存在的值,而void表示可以返回undefined。
- never类型不能赋值给任何类型,而void类型可以赋值给any类型。
- never类型表示一个不存在的值,比如never类型表示一个函数会永远不返回。
- void类型表示一个函数会返回undefined,或者没有返回值。
null和undefined类型
let name: string | null = null
let age: number | undefined = undefinedjavaScript 有两个基础值用于表示值不存在或未初始化的值:null 和 undefined。 TypeScript 有两个对应的同名类型。这些类型的行为取决于你是否启用了 strictNullChecks 选项。
关闭 strictNullChecks,可能是 null 或 undefined 的值仍然可以正常访问,并且值 null 和 undefined 可以分配给任何类型的属性。缺乏对这些值的检查往往是错误的主要来源;
启用 strictNullChecks 时,当值为 null 或 undefined 时,你需要在对该值使用方法或属性之前测试这些值。就像在使用可选属性之前检查 undefined 一样,我们可以使用缩小来检查可能是 null 的值:
function doSomething(x: string | null) {
if (x === null) {
// do nothing
} else {
console.log("Hello, " + x.toUpperCase());
}
}联合类型
联合类型,表示多个类型中的一个
let name: string | number = 'zhangsan'
name = 123
name = true // 错误: 类型“boolean”的参数不能赋给类型“string | number”的参数非空断言
TypeScript 还具有一种特殊的语法,可以在不进行任何显式检查的情况下从类型中删除 null 和 undefined。在任何表达式之后写 ! 实际上是一个类型断言,该值不是 null 或 undefined:
let name: string | null = null
name!.toUpperCase()
name.toUpperCase() // 错误: 类型“null”上不存在属性“toUpperCase”对象类型
创建对象类型,对象类型可以包含多个属性,属性类型可以任意,属性名可以任意
// 固定类型
type Person = {
name: string;
age: number;
sex?: string; // 可选属性
}
const person1: Person = {
name: 'zhangsan',
age: 18
}
const person2: Person = {
name: 'lisi',
age: 19,
sex: 'male'
}
const person3: Person = {
name: 'wangwu',
sex: 'female'
} // 错误: 属性“age”缺少,或者属性“age”的类型不匹配
// 泛型映射类型
// T表示键名类型,U表示键值类型
type Animal<T, U> = {
[key in T]: U;
}
// 比如给猫定义属性
const car: Animal<string, number> = {
speed: 100,
weight: 2000
}
// 统计家禽的数量
const fowl: Animal<'chicken' | 'durk', number> = {
chicken: 18,
durk: 16
}数组和元组
数组和元组,数组和元组都是有序的集合,数组和元组可以包含多个元素,元素类型可以任意,元组可以指定元素类型和数量。
| 特征 | 数组 | 元组 |
|---|---|---|
| 长度约束 | 不限制 | 声明时确定长度 |
| 类型约束 | 不限制 | 确定类型和数量 |
| 赋值约束 | 不限制 | 赋值时类型和数量必须一致 |
| 越界访问 | undefined | 报错 |
| 使用场景 | 存储同类数据(如列表、数据集) | 存储结构化数据(如坐标、返回值、键值对) |
数组
// 数组类型的声明方式
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: Array<string> = ["hello", "world"];
let numbers2: number[] = Array.from({length: 10}).map((_, index) => index + 1)
// 联合类型数组
let mixed: (number | string)[] = [1, "hello", 2, "world"];
// 只读数组
let readonlyNumbers: readonly number[] = [1, 2, 3];
let readonlyStrings: ReadonlyArray<string> = ["a", "b", "c"];
// 多维数组
let matrix: number[][] = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];元组
// 基本元组
let person: [string, number] = ["张进喜", 25];
// 可选元素
let optional: [string, number?] = ["hello"];
// 剩余元素
let rest: [string, ...number[]] = ["hello", 1, 2, 3];
// 只读元组
type StringNumberBooleans = readonly [string, number, ...boolean[]];
const tuple: StringNumberBooleans = ["world", 3, true, false, true];
// 命名元组
type Range = [start: number, end: number];
let range: Range = [0, 100];
// 元组解构
let [name, age] = person;
console.log(`姓名: ${name}, 年龄: ${age}`);枚举
枚举,枚举是一种数据结构,用于定义一组常量,枚举成员会自动赋值,从0开始递增。
enum Direction {
up = 1,
down,
left,
right
}
enum Color {
Red = "#ff0000",
Green = "#00ff00",
Blue = "#0000ff"
}类型断言
类型断言,用于告诉编译器变量的类型,编译器会忽略类型检查。
const container = document.getElementById("container") as HTMLDivElement;
const name: string | null = 'zhangsan'
name.length // 错误: 类型“string | null”上不存在属性“length”
(name as string).length // 正确字面类型
字面类型,用于定义一个值只能是某个具体的值。
let x: "hello" = "hello";
// OK
x = "hello";
// 错误:值“howdy”与类型“"hello"`不匹配
x = "howdy";显然,这种类型是无意义的对于绝大多数场景来说 但可以结合之前使用过的联合类型
function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}
printText("Hello, world", "left");
printText("G'day, mate", "centre");// 错误:值“centre”与类型“"left" | "right" | "center"`不匹配