Typescript快速入门

Posted zhanyd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Typescript快速入门相关的知识,希望对你有一定的参考价值。

文章目录

TypeScript简介

什么是TypeScript?

简单地说TypeScript就是在JavaScript的基础上加上了类型检查。

TypeScript 与 javascript 有着不同寻常的关系。TypeScript 提供了 JavaScript 的所有功能,并在这些功能之上添加了一层: TypeScript 的类型系统。
例如,JavaScript 提供了诸如 string 和 number 这样的原始类型,但它不检查你在赋值时与类型是否匹配。TypeScript 提供了这样的功能。
这意味着你现有的运行良好的 JavaScript 代码也是 TypeScript 代码。TypeScript 的主要好处是,它可以检查代码中的意外行为,从而降低出现错误的机会。
(摘抄自:https://www.typescriptlang.org/zh/docs/handbook/typescript-in-5-minutes.html

TypeScript安装

安装TypeScript需要用npm命令,而npm依赖于Node.js,因此首先得安装Node.js。

Node.js发布于2009年5月,实质是对Chrome V8引擎进行封装。可以在https://nodejs.org官网上下载最新的版本。

Node.js安装很简单,下载之后,按照向导一步一步根据默认配置操作即可,安装完成后,验证下是否安装成功。

在命令行工具中输入“node -v”和“npm -v”查看是否安装成功,如果安装成功就会显示版本号。

安装完npm之后,在命令行工具界面中输入命令“npm install -g typescript”全局安装TypeScript,稍等片刻,等待安装完成后,用命令tsc -v查看其版本号来验证是否安装成功。

第一行TypeScript代码

新建一个hi.ts文件,代码如下:

function hi(msg: string) : string 
    return "hi " + msg


console.log(hi('days'))

用命令 tsc *.ts 编译TypeScript代码,会在同一个目录下生成一个js文件。

tsc hi.ts

编译后的 hi.js JavaScript代码

function hi(msg) 
    return "hi " + msg;

console.log(hi('days'));

我们可以看到上述TypeScript必须给变量指定类型msg: string,而JavaScript代码的变量是不用指定类型的。

这是TypeScript作为一门静态语言和JavaScript作为一门动态语言最大的区别之一:

  • 静态语言是在编译时确定变量的数据类型的语言,需要声明变量的类型,不能随意改变。(TypeScript)
  • 动态语言是在运行时确定变量的数据类型的语言,不需要声明变量的类型,可以根据赋值改变。(JavaScript)

静态语言和动态语言都有各自的优点:

  • 静态语言可以在编译阶段发现错误和优化代码,提高程序的效率和安全性。
  • 动态语言可以在运行时动态改变程序的结构和功能,提高程序的灵活性和表达力。

静态语言可以在编译阶段发现错误和优化代码,这有什么好处呢?

我们来看一个JavaScript的例子:

if (1 < x < 3) 
  // x是 *任何* 值都为真!

为什么这个表达式永远为真呢?

这是因为 JavaScript 的比较运算符是从左到右结合的,所以 if (1 < x < 3) 实际上相当于 if ((1 < x) < 3),先比较 1 和 x 的大小,然后再比较结果和 3 的大小。

而(1 < x)的结果只能是 true 或 false,它们在 JavaScript 中会被转换成数字 1 或 0,所以无论 x 是什么值,if (1 < x < 3) 都会转换成if ((0或者1) < 3),结果永远是 true。

如果想要判断 x 是否在 1 和 3 之间,正确的写法是 if (x > 1 && x < 3),使用逻辑与运算符 && 来连接两个条件。

TypeScript可以在代码运行之前就能发现这样的错误:


如果我们是在编写一个大型的项目,有成千上万行代码,这些奇怪的错误不及时发现,就会造成严重的后果。所以TypeScript就是为了适应大型项目的开发的。

TypeScript的主要特点

编译和擦除类型

TypeScript的类型仅仅是为了在编译的时候检查用的,一旦TypeScript的编译器完成了检查代码的工作,它就会擦除类型最终生成“已编译”的JavaScript代码。

类型注解并不属于 JavaScript(或者专业上所说的 ECMAScript)的内容,所以没有任何浏览器或者运行时能够直接执行不经处理的 TypeScript 代码。

这也是为什么 TypeScript 首先需要一个编译器,因为它需要经过编译,才能去除或者转换TypeScript独有的代码,从而让这些代码可以在浏览器上运行。

这意味着一旦您的代码被编译,生成的普通JavaScript代码便没有类型信息。

TypeScript代码最终是编译成JavaScript代码运行的。

这意味着,如果将代码从JavaScript迁移到TypeScript ,即使TypeScript认为代码有类型错误,也可以保证以相同的方式运行。

保持与JavaScript运行时行为相同是TypeScript的基本特性,你可以轻松地在两种语言之间转换,而不必担心一些细微差别可能会使程序抛出异常而停止工作。

类型推断

TypeScript 可以识别 JavaScript 语言,在许多情况下可以推断类型。

在创建变量并将其赋值给特定值时,TypeScript 可以感知其数据类型,例如 let helloWorld 赋值了字符串,那么 TypeScript 就可以推断出变量 helloWorld 是 string 类型。

定义类型

你可以使用 interface 关键字声明显式地描述此对象的内部数据的类型:

interface User 
  name: string;
  id: number;

然后你可以声明一个符合此接口(interface)的 JavaScript 对象,在变量声明后使用像 : TypeName 这样的语法:

interface User 
  name: string;
  id: number;

// ---分割线---
const user: User = 
  name: "Hayes",
  id: 0,
;

如果提供的数据类型与提供的接口不匹配,TypeScript 会警告:

name在接口中定义成了string类型,而在user对象中赋值为1,就会抛出类型不匹配的警告。

我们还可以定义一个带构造方法的类和接口:

interface User 
  name: string;
  id: number;

 
class UserAccount 
  name: string;
  id: number;
 
  constructor(name: string, id: number) 
    this.name = name;
    this.id = id;
  

 
const user: User = new UserAccount("唐三", 1);

联合类型

联合类型使用管道符号(|)表示一个值可以是多种类型之一。这在函数参数和返回值中非常有用,可以让你处理具有不同类型的输入和输出。

例如:

type StringOrNumber = string | number;

function printValue(value: StringOrNumber) 
  console.log(value);


printValue("hello"); // 输出 "hello"
printValue(42); // 输出 42

在这个例子中,我们创建了一个名为 StringOrNumber 的联合类型,表示值可以是 string 或 number 类型。我们的 printValue 函数接受一个 StringOrNumber 类型的参数,并将其打印到控制台。

泛型

TypeScript 的泛型是一种编程技术,允许你在定义函数、接口和类时使用类型参数,从而实现类型安全的代码重用。泛型在编译时保留类型信息,这有助于捕获类型错误,并提高代码的可维护性和可读性。

在 TypeScript 中,泛型使用尖括号(<>)来表示类型参数。例如,Array 表示一个元素类型为 T 的数组,其中 T 是类型参数。

泛型函数:

假设我们要创建一个函数,将一个数组中的所有元素都包装在一个对象中,如 value: element。我们可以使用泛型来实现这个函数,以便它适用于不同类型的数组:

function wrapInObject<T>(array: T[]) 
    return array.map((element) => (value: element))


console.log(wrapInObject([1,2,3]))  // 输出[  value: 1 ,  value: 2 ,  value: 3  ]
console.log(wrapInObject(['a','b','c'])) // 输出[  value: 'a' ,  value: 'b' ,  value: 'c'  ]

这里,T 是一个类型变量,用于表示元素的类型。当我们实际调用 wrapInObject 时,TypeScript 会根据传入的数组类型推断出 T 的具体类型。

泛型类:

泛型同样可以应用于类。

例如,我们创建一个简单的栈类:

class Stack<T> 
  private items: T[] = [];

  push(item: T): void 
    this.items.push(item);
  

  pop(): T | undefined 
    return this.items.pop();
  


const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 输出:2

const stringStack = new Stack<string>();
stringStack.push("a");
stringStack.push("b");
console.log(stringStack.pop()); // 输出:"b"

在这个例子中,我们定义了一个包含一个类型参数 T 的泛型类 Stack。T 表示栈中元素的类型。当我们创建 Stack 的实例时,需要为 T 指定具体的类型。

接口

TypeScript 的接口(Interface)是一种定义对象结构和约束的方法。接口可以描述对象的形状(即属性和方法),并为类和函数定义约定。通过接口,我们可以确保代码符合预期的结构和行为,提高代码的可读性和可维护性。

接口主要有以下几个用途:

描述对象的形状:

接口可以用来描述对象应该具有哪些属性和方法。这使得我们可以在编写代码时获得类型检查和智能提示,从而减少出错的可能性。

例如,我们可以定义一个描述用户信息的接口:

interface User 
  id: number;
  name: string;
  age: number;


function printUserInfo(user: User): void 
  console.log(`ID: $user.id, Name: $user.name, Age: $user.age`);


const user: User =  id: 1, name: "Alice", age: 30 ;
printUserInfo(user);

在这个例子中,User 接口定义了用户信息应具有的属性。printUserInfo 函数接受一个 User 类型的参数,这样我们可以确保传递给该函数的对象具有正确的结构。

描述函数类型:

接口也可以用来描述函数的类型。这包括函数的参数类型和返回值类型。

例如,我们可以定义一个用于比较两个值的接口:

interface Comparator<T> 
  (a: T, b: T): number;


const numberComparator: Comparator<number> = (a, b) => 
  return a - b;
;

const stringLengthComparator: Comparator<string> = (a, b) => 
  return a.length - b.length;
;

在这个例子中,Comparator 接口定义了一个泛型函数类型,用于比较两个值。我们创建了两个不同类型的比较器:一个用于比较数字,另一个用于比较字符串的长度。

实现接口的类:

类可以实现接口,以确保遵循特定的约定。当一个类实现了一个接口时,TypeScript 会检查该类是否具有接口所要求的属性和方法。

例如,我们可以定义一个表示几何形状的接口和一个实现该接口的类:

interface Shape 
  area(): number;
  perimeter(): number;


class Rectangle implements Shape 
  constructor(private width: number, private height: number) 

  area(): number 
    return this.width * this.height;
  

  perimeter(): number 
    return 2 * (this.width + this.height);
  


const rectangle = new Rectangle(10, 5);
console.log(rectangle.area()); // 输出:50
console.log(rectangle.perimeter()); // 输出:30

在这个例子中,Shape 接口定义了几何形状应具有的方法。Rectangle 类实现了 Shape 接口,确保了它具有正确的方法。

通过使用接口,我们可以确保对象、函数和类具有预期的结构和行为。

运行 .ts 文件的方法

方法一:先将 .ts 文件编译成 .js,再运行 .js 文件

  1. 安装 typescript
npm install -g typescript // 如果已经安装过请忽略这步
  1. 将 .ts 文件编译成 .js 文件,例如文件名为test.ts
tsc test.ts // 会在当前目录下生成对应的 test.js 文件
  1. 运行 .js 文件
node test.js

方法二:通过 ts-node 直接运行 .ts 文件

  1. 安装 typescript、ts-node
npm install -g typescript ts-node
  1. 直接运行 .ts 文件
ts-node test.ts

方法三:在线运行

在浏览器打开:https://www.typescriptlang.org/play
可以在线运行:

总结

TypeScript 是 JavaScript 的一个超集,它在 JavaScript 的基础上引入了一些额外的特性,旨在帮助开发者编写更健壮、易于维护的代码。下面是 TypeScript 的一些主要特点:

  • 静态类型检查:TypeScript 提供了静态类型检查,这意味着在代码运行之前,TypeScript 就能检查代码中的类型错误。这有助于及时发现和修复潜在的问题,降低运行时出现错误的风险。
  • 类型推断:TypeScript 能够根据变量的使用和赋值来推断其类型。这样,在许多情况下,你无需显式地为变量指定类型,TypeScript 会自动为你推断出正确的类型。
  • 泛型:TypeScript 支持泛型编程,允许你创建可以适用于多种类型的函数、类和接口。泛型有助于提高代码的复用性,同时保持类型安全。
  • 接口:TypeScript 的接口可以用来描述对象的形状(即属性和方法),以及定义类和函数的约定。接口可以帮助确保代码符合预期的结构和行为。
  • 类和面向对象编程:TypeScript 提供了对类和面向对象编程特性的完整支持,包括继承、封装、抽象类和访问修饰符等。这有助于组织和管理大型代码库。
  • 装饰器:TypeScript 支持装饰器,这是一种元编程特性,允许你修改或扩展类、属性、方法和参数的行为。装饰器有助于编写可重用和可组合的代码
  • 丰富的工具支持:TypeScript 可以与许多流行的代码编辑器(如 Visual Studio Code)集成,提供智能感知、自动补全、重构等功能。这有助于提高开发者的工作效率。
  • 良好的生态系统:TypeScript 可以与许多现代前端框架(如 Angular、React 和 Vue.js)无缝集成,并拥有大量的类型定义文件,使得你可以轻松地为第三方库添加类型支持。

总之,TypeScript 的特点包括静态类型检查、类型推断、泛型、接口、面向对象编程支持、装饰器以及丰富的工具和生态系统支持。这些特性使得 TypeScript 成为开发大型、可维护的 JavaScript 项目的理想选择。

参考资料:https://www.typescriptlang.org/zh/docs/handbook/typescript-from-scratch.html

Typescript 之 快速入门

Typescript 快速入门

限制变量类型

基本数据类型

// 定义基本数据
let num: number = 3;
let str: string = 'aaa';
let bool: boolean = true;
let count = 2;

基本数据类型就不多赘述了,当给指定了数据类型的变量赋值了非该数据类型的值时就会提示类型错误;

数组

// 定义数组
let arr: number[];
arr = [1, 2, 3]; // 正确
arr = ['a', 2, 3]; // 错误
let arrOfArr: number[][]; // 定义一个二维数组
arrOfArr = [
	[1, 2, 3],
	[4, 5, 6]
]

元组

和数组的定义很类似,只是元组既限制了元素类型,也限制了个数;

// 定义一个元组
let nums: [number, number, number];
nums = [1, 2, 3]; // 和数组很类似,只是限制元素类型以及个数;
// 如果希望其中一个可以省略调的话,只需要在类型后面加个?,那么该数据就既可以有3个,也可以有2个
let counts: [number, number, number?];
counts = [4, 5];

联合类型

// 联合类型
// 当希望某个变量是多个任意类型中的其中一种时:
let color:number | string; // color 既可以是number ,也可以是 string
color = 'red';
color = 111111;
color = true; // 编译器报错
// 利用联合类型实现枚举
let gender: 'male' | 'female'
let n: 1 | 2 | 3 | 4;
gender = 'male'; // 正确
gender = 'aaa'; // 错误
n = 3; // 正确
n = 54; // 错误

小结

需要 注意 的是:对在定义变量时就赋了初始值的普通变量,我们其实不需要明确指定类型,因为编译器能够自动根据初始值做类型推导,如代码中的 count。


限制对象的数据类型

使用 interface,某些字段如果是可选的,定义接口的时候使用 ? 标记即可。

interface User 
	id: number;
	name: string;
	roles?: string[];

// 如果使用该接口定义的对象缺少或者多出了某些属性,编译器报错
let userInfo: User = 
	name: 'zhangsan',
	age: 12, // 报错


// 如果希望对象的某些字段是可选的,可用? 标记该字段,如roles字段,userInfo2中是缺少roles字段的,但是编译器并不会报错。
let userInfo2: User =  // 正确
	id: 202206010001,
	name: 'zhangsan',


类型别名

  • 类型别名: 使用 type关键字,这样定义的好处是,如果我们在其他地方使用到了相同类型,可以直接使用别名来进行代码的复用。
type Id = number | string;

function getName(id: Id) 
	// ......


函数中的typescript

  • 对函数参数进行数据类型检查:
function multiply(a: number, b: string) 
	console.log(a, b)

multiply(1, 'a') // 参数分别只能传入数字、字符串,且两个参数必须
multiply(1, 2) // 提示参数2的类型错误
multiply('a', 'b') // 提示参数1的类型错误
multiply(1) // 提示漏传参

默认情况下没有如果在定义参数的时候没有指定变量的数据类型时,那么默认该参数是 any 类型,换句话说就是 typescript 不会对该参数进行类型检查;

  • 希望函数的某个参数是可选的:
// 假设希望 b 参数是可选的,可传可不传,只需要在该参数后面加一个?即可
function multiply(a: number, b?: string) 
	console.log(a, b)

multiply(1, 'a') // 正确
multiply(1) // 正确
  • 对函数的返回值进行数据类型检查:
function multiply(a: number, b: number): number 
	console.log(a, b)
	return a + b;

let sumNum = multiply(1, 2);

// 或者如果一个函数没有返回值,指定为 void类型即可
function hello(): void 
	alert('hello world!!!');

  • 函数的签名:重点体现在函数参数为 回调函数时
function getName(callBack: (data: string) => void) 
	// 该方法限制了callBack 回调函数的参数为 string 类型,并且没有返回值

// 正确
getName((data) => 
	alert(data);
)
// 错误
getName((data) => 
	alert(data * 2);
)



如有不足,望大家多多指点! 谢谢!

以上是关于Typescript快速入门的主要内容,如果未能解决你的问题,请参考以下文章

Typescript快速入门

Vue+TypeScript使用教程-快速入门

TypeScript入门版~适合初学者快速学习。

TypeScript入门版~适合初学者快速学习。

Vue新搭档TypeScript快速入门实践

技术分享VUE深入浅出&TypeScript快速入门