TypeScript 基础入门TypeScript (TS) 是一种强类型的 JavaScript (JS) 超集,本
TypeScript (TS) 是一种强类型的 JavaScript (JS) 超集,为 JavaScript 提供了类型系统。在大型项目中,数据量十分庞大,TS带来的类型约束能力便能极大地提高代码的可维护性和可读性。本文将带领你从基础的 TypeScript 知识点出发,逐步深入到实际项目中的应用,包括类型约束、接口模块化、泛型等内容。
TypeScript 基础知识
TypeScript 与 JavaScript 的区别
TypeScript 与 JavaScript 的最大区别在于它为 JavaScript 添加了类型系统。JavaScript 是一种动态类型语言,在运行时才会检查数据类型。而 TypeScript 是静态类型语言,可以在编译时发现类型错误,从而减少运行时错误。
// JavaScript
function add(a, b) {
return a + b;
}
// TypeScript
function add(a: number, b: number): number {
return a + b;
}
在 JavaScript 中,add
函数没有类型约束,可能会传入非数值类型参数,导致错误。而在 TypeScript 中,通过指定参数和返回值类型,确保了代码的类型安全性。
TypeScript 中的基本类型
TypeScript 提供了与 JavaScript 相同的基础数据类型,如 number
, string
, boolean
,并新增了一些特殊类型,如 any
, unknown
, never
, void
。
let isDone: boolean = false;
let count: number = 10;
let name: string = 'TypeScript';
let notSure: any = 4; // 可以是任何类型
notSure = 'maybe a string instead';
Type 和 Interface
在 TypeScript 中,type
和 interface
都可以用于定义对象的类型,但它们有一些细微的区别。
type
主要用于定义基本类型的别名、联合类型、元组等。
type ID = number | string;
let userId: ID = 10;
userId = '12345';
interface
更适合用于定义对象类型,并且支持继承和扩展。
interface Person {
name: string;
age: number;
}
let john: Person = {
name: 'John',
age: 25
};
泛型 (Generics) 的使用
泛型允许在定义函数、接口或类时使用类型参数,从而提高代码的复用性和灵活性。
泛型函数
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>('Hello TypeScript');
在上面的例子中,T
是一个类型参数,它可以在函数调用时指定具体的类型。
泛型接口
interface ApiResponse<T> {
data: T;
status: number;
}
const response: ApiResponse<string> = {
data: 'Success',
status: 200
};
TypeScript 实战
现在,我们将结合一个小项目来讲解 TypeScript 的具体应用。在这个项目中,我们通过 TypeScript 为 API 接口添加了类型约束,并使用了泛型来处理 API 返回值。
在项目中,所有的 API 接口都集中放在 /api
目录下,每个模块有独立的接口文件,便于管理,特别是在大型项目中。我们通过 TypeScript 的类型系统,为每个接口函数添加了返回值类型的约束。
API 接口示例
member.ts: 定义 MemberEntity
类型
export interface MemberEntity {
id: number;
login: string;
avatar_url: string;
}
memberApi.ts: 使用泛型为接口函数添加类型约束
import type { MemberEntity } from "../types/member";
import Axios, { AxiosResponse } from "axios";
const githubURL = "https://api.github.com";
const githubMembersUrl = `${githubURL}/orgs/lemoncode/members`;
export const getMembersCollection = (): Promise<MemberEntity[]> => {
const promise = new Promise<MemberEntity[]>((resolve, reject) => {
try {
Axios.get(githubMembersUrl).then(response => {
resolve(mapMemberListApiToModel(response));
});
} catch (ex) {
reject(ex);
}
});
return promise;
};
const mapMemberListApiToModel = ({ data }: AxiosResponse<any[]>): MemberEntity[] => {
return data.map(githubMember => ({
id: githubMember.id,
login: githubMember.login,
avatar_url: githubMember.avatar_url,
}));
};
在 getMembersCollection
函数中,返回值类型定义为 Promise<MemberEntity[]>
,表示函数返回一个包含 MemberEntity
类型数组的 Promise 对象。通过 mapMemberListApiToModel
函数将 API 返回的数据映射为我们定义的 MemberEntity
类型。
结合 Hooks 使用
MemberEntity.tsx: 使用自定义 Hook 加载数据
import { useEffect } from 'react';
import type { MemberEntity } from '../types/member';
import { useMemberCollection } from '../hooks/member';
const MemberEntity = () => {
const { memberCollection, loadMoemberCollection } = useMemberCollection();
useEffect(() => {
loadMoemberCollection();
}, []);
return (
<table>
<thead>
<tr>
<th>Avatar</th>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{memberCollection.map((member: MemberEntity) => (
<tr key={member.id}>
<td><img src={member.avatar_url} alt={member.login} /></td>
<td>{member.id}</td>
<td>{member.login}</td>
</tr>
))}
</tbody>
</table>
);
};
export default MemberEntity;
在这个组件中,我们使用了一个自定义 Hook (useMemberCollection
) 来管理成员数据的加载和状态。通过泛型约束,确保了组件中 memberCollection
的每一项都符合 MemberEntity
类型。
总结
通过本文,我们学习了 TypeScript 的基础知识,包括与 JavaScript 的区别、基本类型、type
和 interface
的用法,以及泛型的应用。在实际项目中,我们通过 TypeScript 提供的强类型系统,提升了代码的健壮性和可维护性,特别是在 API 接口处理和数据类型约束方面。
TypeScript 是现代前端开发中不可或缺的工具,掌握它将帮助你写出更安全、更可维护的代码。在以后的开发中,结合 TypeScript 与 React、Vue 等框架,你可以更轻松地管理和扩展大型项目。
如果这篇文章对你有帮助,可以点个赞哦😊!
转载自:https://juejin.cn/post/7412486655868321830