×

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

独孤求败 独孤求败 发表于2026-06-24 14:07:25 浏览25 评论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";
=123;
=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(instanceofDate){
  a.getTime();// ✅ 安全
}

// 方式3:类型断言
(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 = "函数执行了,但什么都不返回"

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


群贤毕至

访客