TypeScript:初学者终极指南
短时间内从零开始学习 TypeScript 的指南
TypeScript 是 JavaScript 的超集,它通过添加类型和其他功能来扩展语言。
TypeScript 功能:
- 由微软创建
- 2012年发布
- 支持 JavaScript 库
- 面向对象
- 文件扩展名 .ts
- 为提高质量而开发,并在使用 JavaScript 的 Web 应用程序中具有更好的架构
TypeScript 帮助我们:
- 为代码中可能出现的错误更改创建“护栏”
- 更容易检测问题
- 防止与类型和格式相关的问题
- 代码结构更好
- 在我们的项目中有代码指南
您可以在浏览器中开始使用 TypeScript:https://www.typescriptlang.org/play
本指南的要求:
- 操作系统:Windows、Linux、macOS
- Node.JS 16.x >
- 代码编辑器(VS Code、Sublime)
从零开始的项目
要在没有创建项目的情况下首次运行 TypeScript,您可以创建一个包含示例代码的 .ts 文件,然后运行以下命令将此 TypeScript 文件转换为 JavaScript。
npx --package typescript tsc --outDir dist [FileName].ts
要从头开始创建自己的项目,首先,导航到一个空文件夹并创建一个扩展名为 .ts 的文件,然后执行以下命令:
npm init -y
npm install typescript --save-dev
编辑 package.json 文件和 tsc 的脚本部分:
"scripts": {
"tsc": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
然后,您需要运行以下命令来创建 .tsconfig.json 文件
run tsc -- --init
此文件默认有配置,但您可以根据需要进行更改。更多信息请访问:
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
最后,执行以下命令来编译你的 TypeScript 文件并执行最终的 JavaScript 代码:
npm install
npm run tsc
node FileName.js
逐个执行示例
要了解执行示例,您可以访问:
https://github.com/Mteheran/TypeScriptGuide
并执行以下命令
npm install
npm run tsc
node FileName.js
您可以按照第一个文件中的指南,阅读注释以了解上下文,然后执行npm run tsc
以生成 JavaScript 文件并查看使用node [FileName].js
现在您已经了解了与 TypeScript 相关的一般概念,让我们开始逐步学习所有功能。
1.变量
我们使用冒号“:”为变量分配类型。
let number1: number;
let total: number;
Typescript 可以根据设置的值推断类型。
在这种情况下,您不需要指定类型,对于此示例,它将是数字。
let percentage = 100;
您可以在分配类型后创建设置值的常量
const messageResult: string = "The current percentage is:";
不能为常量赋新值。以下代码会报错:
const messageResult: string = "The current percentage is:";
messageResult = "";
如果您尝试将字符串值设置为 number1,您将收到错误,这是使用 TypeScript 的好处
let number1: number;
number1 = "This message";
TypeScript 支持布尔类型。该值可以是 true 或 false
let IsADeveloper: boolean;
IsADeveloper = true;
console.log(`"Is the user a developer? " ${IsADeveloper}`);
一个变量可以有多种类型。在 TypeScript 中,这个概念被称为“联合”。使用管道符可以定义多种类型:
let chapterName : string | number;
chapterName = "Number 1";
chapterName = 1;
2. 附加类型
当变量没有值时,undefined
let emptyVariable : undefined;
空值类型。当你想使用特定类型且可以为空的变量时,这很有用。
let nullVariable: null;
let description: string | null;
使用 any 可以为变量分配任何类型的值
let genericValue: any;
genericValue = 10;
genericValue = "Ten";
将 void 与不返回值或返回 undefined 的函数一起使用
function noReturnsValue() : void
{
console.log("This functions doesn't return a value");
}
当函数永远不会返回值时,用户永远不会
function errorFunction(errorMsg: string): never {
throw new Error(errorMsg);
}
//call error function here
errorFunction("messsage");
3.数组
您可以为特定类型创建数组
let listOfNumber : number[];
listOfNumber = [0, 1, 5, 8, 10];
您可以使用泛型(另一种语法)声明数组。
let listOfNumberGeneric : Array<number> = [0, 1, 5, 8, 10];
let sumOfNumbers = listOfNumber.reduce((p,value)=> p+value);
console.log(`The sum is: ${sumOfNumbers}`);
您可以使用“any”创建一个数组来支持多种类型;
let listOfItems : any[];
listOfItems = [0, true, 'Name', 8, 'A text value'];
4. 枚举
你可以创建一个枚举来使用包含某些特定值的类型。将枚举创建为常量是一种很好的做法
const enum dayOfWeek
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
使用枚举作为类型使代码更容易理解。
let currentDayOfWeek : dayOfWeek;
currentDayOfWeek = dayOfWeek.Saturday;
console.log(`The current day is: ${currentDayOfWeek} `);
枚举在条件验证中非常有用。你可以轻松识别该值的含义:
if(currentDayOfWeek === dayOfWeek.Saturday || currentDayOfWeek == dayOfWeek.Sunday)
{
console.log(`it's weekend!!!!`);
}
5. 元组
您可以声明一个由 2 个或更多值组成的新变量(这是一个元组)。
const fullName : [string, string] = ["Miguel", "Teheran"];
您可以在元组中使用不同的类型。
//product name, cost and quantity example:
const product : [string, number, number] = ["Tomato", 1, 50];
您可以创建一个元组数组
var employee: [number, string][];
employee = [[1, "Steve"], [2, "Bill"], [3, "Jeff"]];
您可以使用位置访问元组中的属性
const fullName : [string, string] = ["Miguel", "Teheran"];
console.log(fullName[0]); //prints Miguel
console.log(fullName[1]); //prints Teheran
6. 功能
您可以在函数中指定参数的类型
function printDoubleNumber(number: number) : void
{
console.log(number * 1);
}
您可以将其与函数一起用作表达式
const printDoubleNumberExpression = function printDoubleNumber(number: number) : void
{
console.log(number * 1);
}
您还可以使用箭头功能
const printDoubleNumberArrow = (number: number) : void =>
{
console.log(number * 1);
}
您可以定义要在函数中返回的特定类型
const plusNumbers = (number1: number, number2: number) : number =>
{
return number1 + number2;
}
TypeScript 使用问号支持可选参数
const concactStrings = (title: string, name?: string) =>
{
console.log(`${title} ${name}`);
}
您可以通过在定义中设置值来指定参数的默认值
const calculateTax = (productPrice: number, taxPercentage: number = 0.16): number =>
{
return productPrice * taxPercentage;
}
使用 rest 参数来接收具有默认类型的更多参数
const setConfiguration = (IsActivated:boolean, ...options: Array<string>): void =>
{
console.log(`Configuration is activated ${IsActivated}`)
}
7.类型
在 TypeScript 中,你可以通过添加属性名称和类型来创建类型。类型是由多个属性组成的复杂类型。使用问号可以将 undefined 设置为可能值(这意味着可选值)。
type Person =
{
id: number,
name: string,
lastName: string,
phone?: string, //with the question mark you set undefined as a possible value
}
var newPerson : Person = {id : 1, name: "Miguel", lastName: "Mendez"} ;
newPerson.lastName = "Teheran";
console.log(`I am ${newPerson.name} ${newPerson.lastName}`);
当你在函数中使用类型时,可以使用解构来获取特定属性的值:
const printFullName = ({name, lastName}: Person) =>
{
console.log(`My fullname is ${name} ${lastName}`);
}
printFullName(newPerson);
8. 课程
类是一个包含代码的模板,用于创建具有特定数据的实例。类可以包含函数、属性、构造函数和数据。
class SmarPhone {
color: string
brand: SmartPhoneBrand
price:number
constructor() {
//default values using constructor
this.color = "white";
this.brand = SmartPhoneBrand.Other;
this.price = 0;
}
//you can initialize and create the properties directly in the constructor
//constructor(public color: string, public brand: SmartPhoneBrand, public price: number) {
// this.color = "white";
// this.brand = SmartPhoneBrand.Other;
// this.price = 0;
//}
setPrice(smartPhonePrice: number) : void
{
this.price = smartPhonePrice;
}
}
//example of a enumeration used in the class
const enum SmartPhoneBrand {
Apple,
Xiaomi,
Sansumg,
Motorola,
Other
}
var mySmartPhone = new SmarPhone();
mySmartPhone.brand = SmartPhoneBrand.Apple;
console.log(`my cellphone is ${mySmartPhone.brand} ${mySmartPhone.color}
nad the price is ${mySmartPhone.price}`);
您可以从类或抽象类扩展。抽象类无法实现。
abstract class Card {
//creating and initializing the properties using the constructor
constructor(public cardNumber: number, public owner: string) {}
}
//you need to use super to pass the parameters to the parent class
class CreditCard extends Card {
constructor(public balance: number, cardNumber: number, owner: string) {
super(cardNumber, owner);
}
}
var masterCard = new CreditCard(1000, 11225533645, "Jhon Doe");
9. 泛型
使用泛型,你可以对两种或更多种类型使用相同的函数
function WhatIsThisType<T>(value: T): string {
return typeof(value);
}
//when you call the function you can specify the type that you want to use
console.log(WhatIsThisType<number>(100));
console.log(WhatIsThisType<boolean>(true));
console.log(WhatIsThisType<string>("string value"));
您可以将接口与泛型结合使用:
interface collectionList<T> {
id: number,
name: string,
description: string,
items: T[] | undefined | null
}
使用上一个界面时,您可以指定 collections 和 items 属性的类型
var newCollection : collectionList<number> = {
id: 1,
name: "New collection",
description: "This is a new collection",
items: [10, 20, 30]
}
您还可以使用泛型进行扩展,以在类型中默认包含特定属性
interface HasId
{
id:number;
}
class Item implements HasId {
constructor(public id:number) {}
}
class GenericModel<T extends HasId> {
items: T[] | undefined
constructor(public name:string) {}
getItembyId(id:number) {
return this.items?.find(p=> p.id === id);
}
}
当你只想设置泛型类的某些值时,可以使用 Partial
const simpleCollection = {
name: 'This is a partial collection',
items: ["Item1", "Item2"]
}
const partialCollection: Partial<collectionList<string>> = simpleCollection;
10. 接口
接口定义了数据的“形状”。它包含通用定义和复杂类型的结构。它定义了在应用程序中的组件之间传递的数据类型。接口是代码中的共享契约。
interface User
{
id: number,
name: string,
lastName: string,
password: string
rol: Rol
email?: string, // optional parameter using question mark
resetPassWord(password: string): boolean //you can properties but also functions to an interface (without implementation)
}
interface Rol
{
id: number,
rolName: string,
levelPermission: number
}
您可以使用接口来创建遵循以下格式的对象,包括函数和属性:
let newRol : Rol =
{
id: 1,
rolName: "Admin",
levelPermission: 0
}
let newUser : User =
{
id: 1,
name: "Miguel",
lastName: "Teheran",
password: "****",
rol: newRol,
resetPassWord: function (password: string): boolean {
this.password = password;
return true;
}
}
接口与类型
-
接口代表对象数据结构
-
类型是表示原始类型和对象(如数据结构)的别名
-
两者都很好,但接口更通用且更严格
-
类型可以具有原始值接口,但不能:
type Person = string |
{
id: number,
name: string,
lastName: string,
phone?: string, //with the question mark you set undefined as a possible value
}
您已经了解了 TypeScript 中的所有常规功能,现在您可以开始使用 TypeScript 启动项目并学习高级主题。
文章来源:https://dev.to/mteheran/typescript-ultimate-guide-for-beginners-1dlo