TypeScript 入门
在 Twitter 上关注我:https://twitter.com/EricTheCoder_
什么是 Typescript?
TypeScript 是 JavaScript 超集
TypeScript 和 Javascript 一样吗?
是也不是。TypeScript 是由微软创建的,并且建立在 JavaScript 之上。
简而言之,它与 Javascript 相同,但具有附加功能。
你从 Javascript 学到的一切在 TypeScript 中都会有用。
我应该先学哪一个?
你肯定要先学习 JavaScript。如果你不懂 JavaScript,那么学习和理解 TypeScript 将会很困难。
为什么要创建一种新语言?JavaScript 就没问题,不是吗?
当人们开始在复杂的应用程序中使用 JavaScript 时,他们很快意识到 JavaScript 在 OOP 方面变得难以工作并且很难发现一些错误。
TypeScript 是由微软开发的,用于弥补这一差距。
那么 TypeScript 到底为 JavaScript 添加了什么呢?
- 强大的类型系统
- 开发时进行类型错误检查
- 更好的面向对象编程
- 新功能,如接口、泛型等。
- 像装饰器一样的元编程
- 编译为可以在旧版浏览器上运行的 JavaScript
- 编辑器中的代码自动完成
- 还有更多...
还有什么我应该知道的吗?
TypeScript 不像 Javascript 那样可以在浏览器或 Node.js 中运行。要执行 TypeScript,需要将其转换/编译为 Javascript。
使用 TypeScript 需要使用编译器。例如,如果你有一个文件名 app.ts,TypeScript 编译器会创建与 JavaScript 等效的 app.js 文件。该文件将用于运行你的应用程序。
这就是为什么我们说 TypeScript 在开发时有帮助。
如何安装和使用 TypeScript 编译器
您可以使用此命令在开发机器上全局安装 TypeScript
$ npm install -g typescript
执行编译器
$ tsc app.js
// or watch mode
$ tsc app.js -w
在监视模式下,TypeScript 将在每次保存时自动重新编译 app.js 中的 app.ts。
TypeScript 配置?
TypeScript 有很多可用的配置/设置。我不会在这篇介绍文章中介绍这些,只是想让你知道 TypeScript 设置存储在一个名为 tsconfig.json 的文件中。你可以使用以下命令创建此文件:
$ tsc --int
TypeScript 101
现在您将学习如何使用基本的 TypeScript 功能
核心类型
TypeScript 最有价值的特性之一是类型系统。在 TypeScript 中,你可以为变量分配一个类型,如果代码中任何地方不符合该类型,TypeScript 编译器就会抛出错误。
为了了解类型,我们将进行 TypeScript 与 Javascript 的比较。
下面是一个常规的 Javascript 代码
function add(num1, num2) {
return num1 + num2
}
const result1 = add(10, 20). // 30
const result2 = add("10", "20") // 1020
在此示例中,result1 为 30,result2 为 1020
为什么result2不是30?
由于您提供了双引号,因此 Javascript 认为您的参数是字符串,因此会按照该逻辑执行代码而不会报告任何错误。
现在想象一下,这个错误会给会计应用程序带来多大的损失。在一个十万行代码的 Web 应用程序中查找这种错误非常困难,非常令人沮丧,而且非常耗时。
TypeScript 来救援!
让我们使用上面相同的代码,但是使用 TypeScript
function add(num1: number, num2: number) {
return num1 + num2
}
const result1 = add(10, 20). // 30
const result2 = add("10", "20") // editor/compile error
唯一的区别是在参数名称后添加了 :number 类型
在这个例子中,'const result2 = add("10", "20")' 行将在代码编辑器和编译时报告错误。
类型推断
当变量初始化时,TypeScript 可以自动推断/检测变量的类型
let amount: number = 99.95
// same as
let amount = 99.95 // best practice
两个变量都是数字类型。最佳做法是让 TypeScript 推断完成它的工作,因为我们自己设置了初始值。这有助于避免重复代码。
请注意,我们仅当变量未用值初始化时才指定类型
let title: string
title = "Hello World"
对象类型
TypeScript 还将自动推断对象类型
const person = {
name: 'Mike Taylor',
age: 45
}
将导致 TypeScript 对象类型
const person: {
name: string;
age: number;
} = {
name: 'Mike Taylor',
age: 45
}
数组类型
const names: string[] = ['Mike', 'John', 'Paul']
const amounts: number[] = [100, 200, 300]
元组类型
当我们需要数组中固定数量的值时使用。
const names: [number, string] = [100, 'Mike']
埃蒙型
Enum主要用于给常量赋值
enum Role { ADMIN, READ_ONLY, AUTHOR }
console.log(Role.ADMIN) // 0
您还可以指定密钥(密钥可以是任何类型)
enum Role { ADMIN = 100, READ_ONLY = 200, AUTHOR = 300 }
console.log(Role.ADMIN) // 100
任何类型
如果您确实不知道类型,请使用 any 作为后备。
let title: any
title = 25
title = 'Hello World'
请注意,这不是一个好的做法。尽量避免!
联合类型
变量可以灵活分配两种类型
function combine(item1: (string | number), item2: (string | number)) {
if (typeof item1 === 'number' && typeof item2 === 'number') {
console.log(item1 + item2)
} else {
console.log(item1.toString() + item2.toString())
}
}
联合类型的语法是:type2 | type2
类型别名
我们可以创建一个自定义类型作为别名,例如联合类型
type Dual = number | string
let title: Dual
title = "Hello"
title = 100
对象类型别名
type User = { name: string; age: number }
const user1: User { name: 'Mike', age: 25 }
// the syntax is then simplyfy
function loadUser(user: User) {
..do something...
}
// instead of
function loadUser(user { name: stringl age: number }) {
..do something...
}
函数返回类型
我们可以指定函数的返回类型
function add(num1: number, num2: number): number {
return num1 + num2
}
Void 返回类型
当函数不返回任何值时,TypeScript 将推断该函数的类型为“void”
function displayMessage(): void {
console.log('Hi there')
}
函数类型
声明语法是:(var:type,var:type)⇒返回类型
function add(num1: number, num2: number): number {
return num1 + num2
}
let calc: Function
// or more specific
let calc: (num1: number, num2: number) => number
calc = add
console.log(calc(10,20))
未知类型
除非我们检查赋值的类型,否则未知类型的变量将无法赋值。
let userInput: unknown
if (typeof userInput === 'string') {
userName = userInout
}
TypeScript 中的 OOP
类声明
class Product {
name: string;
price: number;
constructor(name: string, price: number) {
this.name = name
this.price = price
}
}
const product1 = new Product('iPad', 500)
简写属性初始化
class Product {
constructor(private name: string, private price: number) {
}
}
const product1 = new Product('iPad', 500)
访问修饰符(私有、公共、只读、受保护)
class Product {
private name: string;
private price: number;
constructor(name: string, price: number) {
this.name = name
this.price = price
}
public displayProduct() {
console.log(this.name, this.price)
}
}
const product1 = new Product('iPad', 500)
public 关键字是可选的,因为如果没有提供,它就是默认的修饰符。
p* ublic * 表示类外部可用的变量或函数
p* rivate * 用于类外不可用的变量或函数
readonly是变量 private 和 readonly
Protected 指的是仅在类或子类内部可用的变量或函数
继承
class Friends extends Person {
}
Getter 和 Setter
class Friend {
get name() {
}
set name(value: string) {
}
}
静态属性和方法
class Product {
static defaultName = 'Product x'
static display name() {
console.log(defaultName)
}
}
Person.display('iPad')
界面
interface IsPerson {
name: string;
age: number;
speak(a: string) {
console.log(a)
}
}
const me: IsPerson = {
name: 'Mike',
age: 25,
speak(text: string): void {
console.log(text)
}
}
class customer implements IsPerson {
private name
private age
constructor(name: string, age: number) {
this.name = name
this.age = age
}
public speak(text: string): void {
console.log(text)
}
}
泛型
编写程序时,最重要的方面之一是构建可重用的组件。这可以确保程序具有灵活性以及长期可扩展性。
泛型提供了一种创建可重用组件的方法。泛型使组件能够处理任何数据类型,而不局限于一种数据类型。因此,组件可以被多种数据类型调用或使用。
例如,如果我们想创建一个具有数据属性的接口,该属性可以包含不同的对象类型
首先创建界面
interface Person<T> {
name: string;
age: number;
data: T;
}
<T> 是 TypeScript 在编译时添加的类型的占位符
然后您可以在代码中使用通用接口
const person1: Person<string> = {
name: 'Mike',
age: 25,
data: 'Info about person'
}
// or
const person1: Person<string[]> = {
name: 'Mike',
age: 25,
data: ['Info about person', 'info2']
}
在上面的例子中,相同的接口被用来存储字符串和字符串数组。
鏂囩珷鏉ユ簮锛�https://dev.to/ericchapman/your-first-introduction-to-typescript-3p6h