×

Typescript(一) 环境搭建与十二大基础属性

独孤求败 独孤求败 发表于2026-06-24 14:07:25 浏览75 评论0

抢沙发发表评论

Typescript(一) 环境搭建与十二大基础属性

TS 环境搭建
安装环境依赖
■
通过 npm(Node.js 包管理器)

针对npm 用户可以安装包依赖

npm i typescript -g

然后再安装tsx 运行

npm i tsx -g
测试一下
■

在一个新的文件夹里面新建一个Basic1.ts 文件


■

写入如下代码


constgetTime:()=>void=()=>{
console.log(newDate().toLocaleString());
};
getTime();
运行一下
tsx Basic1.ts
■
结果

2022/6/15 21:17:46
TS十二大类型
■
数字类型 number

■
字符串类型 string

■
布尔类型 boolean

■
空类型 null

■
未定义类型 undefined

■
数组类型 array

■
对象类型 object

■
元组类型 tuple

■
任意类型 any

■
未知类型 unknown

■
never类型 never

■
没有返回值类型 void

数字类型
■
整数类型 number

■
浮点数类型 number

■
大整数类型 bigint

const test_number_1:number=100;
const test_number_2:number=100.5;
const test_number_3: bigint =100n;

console.log(test_number_1);// 100
console.log(test_number_2);// 100.5
console.log(test_number_3);// 100n
布尔类型
const test_boolean_1:boolean=true;

console.log(test_boolean_1);// true

const test_boolean_2:boolean=false;

console.log(test_boolean_2);// false
字符串类型
const test_string_1:string="hello world";

console.log(test_string_1);// hello world
空类型 null
const test_null_1:null=null;

console.log(test_null_1);// null
未定义类型 undefined
const test_undefined_1:undefined=undefined;

console.log(test_undefined_1);// undefined
数组类型 array
const test_array_1:number[]=[1,2,3,4,5];

console.log(test_array_1);// [1, 2, 3, 4, 5]

const test_array_2:string[]=["hello","world"];

console.log(test_array_2);// ["hello", "world"]

// 数组和字符串混用
const test_array_3:(number|string)[]=[100,"hello",200,"world"];

console.log(test_array_3);// [100, "hello", 200, "world"]
对象类型 object
使用
// 可以赋值对象、数组、函数等
const obj: object ={};
const arr: object =[1,2,3];
const fn:object=()=>{};

对象类型 object 非常宽泛,只能访问对象共有的方法.比如(valueOf(),equals(),hashCode(),toString(),equals(),hashCode()).

限制
const person: object ={ name:"Alice", age:25};

// ❌ 错误:不能访问具体属性
console.log(person.name);// Property 'name' does not exist on type 'object'

// ✅ 只能访问 Object 原型上的方法
console.log(person.toString());
更精确的定义

我们一般使用接口来定义对象的属性和方法.

// 1. 对象字面量类型(推荐)
const person:{ name:string; age:number}={ name:"Alice", age:25};

// 2. interface
interface Person {
  name:string;
  age:number;
}
const p: Person ={ name:"Bob", age:30};

// 3. Record
const map: Record<string,number>={ a:1, b:2};

// 4. 索引签名
const dict:{[key:string]:any}={};
dict["name"]="Alice";
dict["age"]=25;
console.log(dict);
// { name: 'Alice', age: 25 }
比较

object vs Object vs {}

类型
说明
object
非原始类型(推荐用于"任意对象")
Object
JS 的 Object 构造函数类型,包含原始类型包装器
{}
空对象类型,几乎包含所有值(除 null / undefined )

举例
// object 不接受原始类型
const x: object ="hello";// ❌ 错误

// Object 接受原始类型(自动装箱)
const y: Object ="hello";// ✅ 可以
总结

需要 任意对象 时:用 object
需要 具体结构 时:用 interface / 类型别名 / 字面量类型
避免使用 Object 和 {} 作为类型,它们行为怪异

元组类型 tuple
元组(Tuple)是固定长度、固定类型的数组。
// 定义:第一个元素是 string,第二个是 number
const user:[string,number]=["Alice",25];

// 访问元素(类型已知)
const name = user[0];// string
const age = user[1];// number

// ❌ 越界访问会报错
const x = user[2];// Tuple type '[string, number]' of length '2' has no element at index '2'
可选元素
// 第三个元素可选
const coords:[number,number,number?]=[10,20];
// 或
const coords2:[number,number,number?]=[10,20,30];
剩余元素
// 前两个固定,后面任意多个 string
const log:[string,string,...string[]]=[
"INFO",
"module",
"detail1",
"detail2",
];
只读元组
const point:readonly[number,number]=[10,20];

// ❌ 不可修改
point[0]=100;// Cannot assign to '0' because it is a read-only property
具名元组
const user:[name:string, age:number]=["Alice",25];

// 解构时更有语义
const[name, age]= user;
与数组的区别

特性
元组[string,number]
数组string
长度
固定
可变
元素位置类型
每个位置类型固定
所有位置类型统一
越界访问
报错
允许

实际使用场景
// useState 返回的就是元组
// [number, Dispatch<<SetStateAction<number>>]
const[count, setCount]=useState(0);

// 函数返回多个值
functiongetUser():[string,number]{
return["Alice",25];
}

// CSV 行解析
const row:[string,string,number,boolean]=["Alice","Engineer",25,true];
注意事项

push 不会检查类型的安全性,会破坏元组的类型约束。

// ❌ 长度不匹配
const bad:[string,number]=["Alice"];// 缺少元素
const bad2:[string,number]=["Alice",25,1];// 元素过多

// ⚠️ push 不会检查类型安全(设计限制)
const t:[string,number]=["Alice",25];
t.push("extra");// 不报错,但破坏元组约束
any 类型

在 TypeScript 中, any 是最宽松的类型,表示"任意类型",会关闭该变量的类型检查。

基本用法
let value:any=4;
value ="hello";// ✅ 不报错
value =true;// ✅ 不报错
value ={};// ✅ 不报错

// 可以访问任意属性、调用任意方法
value.foo.bar();// ✅ 编译不报错(运行可能报错)
使用场景
// 逐步迁移时,先标记为 any,后续再细化类型
functionlegacyFunction(data:any):any{
return data;
}
第三方库无类型定义
// 库没有 @types 声明文件
const untypedLib:any=require("some-untyped-lib");
动态内容
// JSON 解析结果
const parsed:any=JSON.parse(jsonString);

// 用户输入
const userInput:any=getDynamicData();
明确需要绕过类型检查
// 测试时临时绕过
const temp:any= complicatedObject;
危险操作
let x:any="hello";

// 以下全部编译通过,但运行时可能崩溃
x.toFixed(2);// ❌ 运行时错误:字符串没有 toFixed
x[999].name;// ❌ 运行时错误
x();// ❌ 运行时错误:不是函数
newx();// ❌ 运行时错误
与unknown类型对比

unknown 是类型安全的 any

let a:any=4;
a.toFixed();// ✅ 编译通过(危险)

let u:unknown=4;
u.toFixed();// ❌ 错误:需要先类型收窄

// unknown 必须检查后才能使用
if(typeof u ==="number"){
  u.toFixed();// ✅ 安全
}

特性
any
unknown
可赋值给任何类型
✅
❌
可访问任何属性
✅
❌
类型安全
❌ 关闭检查
✅ 必须收窄
推荐度
尽量避免
优先使用

最佳实践
// ❌ 滥用 any
functionbad(data:any):any{
return data.map((x)=> x.id);
}

// ✅ 尽量用具体类型或泛型
functiongood<T>(data:T[]):T[]{
return data;
}

// ✅ 不得不用时,优先 unknown
functionbetter(data:unknown):void{
if(Array.isArray(data)){
// 安全使用
}
}

// ✅ 类型断言(明确知道类型时)
functionok(data:unknown){
const str = data asstring;
return str.length;
}
总结

any = 关闭类型检查,编译器不再帮你

能不用就不用,用 unknown 或具体类型替代

遗留代码迁移时可用,但要逐步替换

开启 strict / noImplicitAny 防止隐式扩散

unknown 类型

ypeScript 中 unknown 是 类型安全的 any ,表示"值可以是任何类型,但使用前必须先检查"。

基本用法
let a:unknown="hello";
a =123;
a =true;

// 直接使用会报错
a.toString();// ❌ 错误:'a' is of type 'unknown'
必须先做类型检查
let a:unknown="hello";

// 方式1:typeof 检查
if(typeof a ==="string"){
  a.toUpperCase();// ✅ 安全,TS 自动收窄为 string
}

// 方式2:instanceof 检查
if(a instanceofDate){
  a.getTime();// ✅ 安全
}

// 方式3:类型断言
(a asstring).toUpperCase();// ✅ 但断言不安全,需确保正确

// 方式4:类型守卫函数
functionisString(x:unknown): x isstring{
returntypeof x ==="string";
}
if(isString(a)){
  a.toUpperCase();// ✅ 安全
}

特性
any
unknown
赋值兼容性
可以复制给任何类型
只能赋值给any和unknown
操作限制
任意操作
必须检查后才能不能直接操作
安全性
关闭检查,危险
安全检查,必须先类型收窄
使用场景
迁移旧代码
新代码首选

举例
let x:any=1;
let y:string= x;// ✅ 不报错,但运行时可能出错

let a:unknown=1;
let b:string= a;// ❌ 报错
let c:string= a asstring;// ✅ 强制断言
实际应用场景(一)
■
JSON解析

functionparseJSON(json:string):unknown{
returnJSON.parse(json);// 返回 unknown 而不是 any
}

const data =parseJSON('{"name": "张三"}');
// data.name  // ❌ 报错,必须先检查

if(typeof data ==="object"&& data !==null&&"name"in data){
console.log(data.name);// ✅ 安全
}
实际应用场景(二)
■
函数参数不确定类型

functionprocessInput(input:unknown){
if(typeof input ==="string"){
return input.trim();
}
if(Array.isArray(input)){
return input.length;
}
return input;
}
■
类型安全的错误处理

try{
// ...
}catch(error:unknown){
// TS 4.0+ 推荐 unknown
if(error instanceofError){
console.log(error.message);// ✅ 安全
}
}
核心原则

能用 unknown 就不用 any — unknown 强制你做类型检查,在编译期捕获错误而不是运行期崩溃。

never 类型

TypeScript 中 never 表示 永远不会发生的值 的类型,是 所有类型的子类型 。一般用于抛出异常

核心用法(一)

抛出异常

// 抛出异常,不会正常返回
functionthrowError(msg:string):never{
thrownewError(msg);
}

// 死循环,不会结束
functioninfiniteLoop():never{
while(true){}
}
核心用法(二)

穷尽检查

配合 switch 或 if-else 确保所有情况都被处理:

typeShape=
|{ kind:"circle"; radius:number}
|{ kind:"square"; side:number}
|{ kind:"triangle"; base:number; height:number};

functiongetArea(shape: Shape):number{
switch(shape.kind){
case"circle":
return Math.PI* shape.radius **2;
case"square":
return shape.side **2;
case"triangle":
return(shape.base * shape.height)/2;
default:
// 如果上面漏了某个 case,这里 shape 就是 never
const _exhaustive:never= shape;
return _exhaustive;
}
}

如果以后给 Shape 添加新类型但忘记处理, never 会报错。

核心用法(三)

从联合类型中排除

typeA=string|number|never;
// 等价于:type A = string | number
// never 在联合类型中自动被忽略
与void 类型的区别

说明
void
never
含义
没有返回值
永远不会返回
可以赋值
undefined
任何值都不能赋值给never

记忆方法

never= 不可能存在,用于:异常函数、穷尽检查、从联合类型中移除

void 类型

TypeScript 中 void 表示 函数没有返回值 或 返回值被忽略 。

基本用法
■
函数没有return

functionlogMessage(msg:string):void{
console.log(msg);
// 没有 return 语句
}

functiondoSomething():void{
const a =1+2;
// 计算完,不返回结果
}
■
显式 return undefined

functionmaybeLog(msg:string):void{
if(!msg)return;// return undefined
console.log(msg);
}
■
与undefined区别

说明
void
undefined
含义
没有返回值的概念
一个具体的值
使用场景
函数返回类型
变量类型,可选值
赋值
void变量可以赋值undefined
只能赋undefined

■
代码如下

functionf1():void{}
functionf2():undefined{
returnundefined;
}

let a:void=undefined;// ✅
let b:void=null;// ❌ strictNullChecks 下报错

let c:undefined=f1();// ❌ void 不能赋给 undefined
let d:void=f2();// ✅ undefined 可以赋给 void
实际场景
■
回调函数

// 不关心回调的返回值
functionfetchData(callback:(data:string)=>void):void{
const data ="result";
callback(data);// 返回值被忽略
}

fetchData((data)=>{
console.log(data);
return123;// ✅ 允许,但返回值被忽略
});
■
接口中的方法

interfaceLogger{
log(msg:string):void;
error(msg:string):void;
}

classConsoleLoggerimplementsLogger{
log(msg:string):void{
console.log(msg);
}
error(msg:string):void{
console.error(msg);
}
}
■
箭头函数

const arr =[1,2,3];

// 明确无返回值
arr.forEach((item):void=>{
console.log(item);
});

// 与有返回值的对比
const doubled = arr.map((item):number=>{
return item *2;
});
核心记忆

void = "函数执行了,但什么都不返回"

用于:回调函数、副作用函数、明确忽略返回值


群贤毕至

访客