Seajs seo外包优化 angularjs版本 vue添加class jq去除空格 jquery获取元素 pr序列设置哪个好 h5下拉刷新 less比较级 完全去vm去虚拟化工具 mysql 选择数据库 python文件 python做界面 java重载和重写 java框架 shell编程学习 linux中sudo linuxshell编程 网页游戏开发入门 vbs脚本 内存整理工具 梦幻西游手游助手 c语言指数函数 lol语音包 微信砍价软件 证书小精灵 python数组赋值 脚本网站 任务管理软件 固态硬盘有什么用 微信群群发软件 街机roms下载 苹果手机怎么添加邮箱 img转iso python私有变量 如何去掉抖音水印 电子海图 鼠标特效代码 和彩云是什么 主题软件
当前位置: 首页 > 学习教程  > 编程语言

大前端进击之路(四)TypeScript入门基础

2021/1/13 20:34:04 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

打工人!打工魂!前端才是人上人!此系列总结于大前端进击之路过程中的学习,如果文章中有不对的地方,希望大家能进行批评改正,互相进步。转载请注明出处。 语言类型 类型安全 强类型 在语言层面限制函数的实…

在这里插入图片描述

打工人!打工魂!前端才是人上人!此系列总结于大前端进击之路过程中的学习,如果文章中有不对的地方,希望大家能进行批评改正,互相进步。转载请注明出处。

语言类型

类型安全

  • 强类型

在语言层面限制函数的实参类型必须与形参类型相同,不允许任意的隐式类型转换。

  • 弱类型

弱类型不限制实参的类型,允许任意的隐式类型转换。

funciton sum(a, b) {
    console.log(a + b)
}
sum(1,2)  // 打印 3
sum(1,'a') //打印 1a

类型系统

  • 静态类型

一个变量声明时,它的类型就是明确的,声明过后,它的类型不允许再被修改。

  • 动态类型

变量的类型随时可以改变,运行阶段才能明确变量类型,变量没有类型,变量存放的值是有类型的。

var a 
a = 'hello'
console.log(a)  // hello
a = 123
console.log(a)  // 123

JavaScript自有类型系统的问题

通过上面我们了解了强类型和弱类型、动态类型和静态类型,我们可以知道JavaScript语言是弱类型、动态类型的。这是因为早期JavaScript编写的应用比较简单,没有编译环节。类似上面的例子我们写了一个两个数相加的sum函数,我们只是想要让两个数字相加,但是如果我们参数输入了字符串,得到的结果就会是字符串拼接。这就是弱类型的问题,让我们的代码不可靠,不能及时发现问题。

强类型的优势

  • 错误更早暴露
  • 编码更准确,代码更加智能
  • 重构更可靠
  • 减少不必要的类型判断

TypeScript基础

TypeScript是什么?

TypeScript是一种由微软开发的自由、开源的编程语言。它是JavaScript的一个超集,本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。任何一个JavaScript运行环境都支持它,TypeScript提供最新的和不断发展的JavaScript特性,功能更加强大,生态也更健全、更完善。

在这里插入图片描述
在这里插入图片描述

缺点:

  • 项目初期,使用TypeScript会增加成本。
  • 语言本身相对于JavaScript多出一些新的概念,增加学习成本。

但是TypeScript是渐进式的,我们会使用JavaScript的语法可直接上手TypeScript。

TypeScript初体验

安装TypeScript

npm install -g typescript

配置文件

生成配置文件tsconfig.json

tsc --init

在这里插入图片描述

// 在生成的配置文件中比较常用的配置选项
// target  => 编译目标为es5
// lib     => 标准库声明,这里我们引用了ES2015、DOM、ES2017
// outDir  => 编译后文件存放位置
// rootDir => 文件根路径

编译TypeScript文件

// 如果我们配置好tsconfig.json文件后可直接使用tsc命令编译
tsc

// 如果我们没有配置好tsconfig.json文件
tsc xxx.ts
// 会给我们生成xxx.js

作用域问题

在TypeScript中会默认文件中的成员会作为全局成员,如果多个文件中有多个相同成员就会出现冲突。

解决办法:

  1. 使用IIFE提供独立作用域
(function () {
    const a = 123
}())
  1. 在当前文件使用export,也就是把当前文件变成一个模块,模块具有单独的作用域。
const a = 123
export {}

基本数据类型

原始数据类型

基础类型分为string、number、boolean、null、undefined、Symbol、void。

const str:string = 'string'
const num:number = 1
const boo:boolean = true
const n:null = null
const u:undefined = undefined
const s:Symbol = Symbol()
const v:void = undefined

Object类型

Object是指除了原始数据类型以外的其它类型

const fun:object = function () {}

const obj:{name:string, age:number} = {
    name : 'xm',
    age : 25
}

Array类型

// 1.可以在元素类型后面街上[],表示由此类型元素组成的一个数组
let arr : number[] = [1,2,3]
// 2.也可以使用数组泛型
let arr : Array<number> = [1,2,3]

元祖Tuple

元祖类型表示一个规定好元素数量和类型的数组。

let arr : [string, number] = ['xm',20]

枚举Enum

使用枚举我们可以定义一些带名字的敞亮,可以清晰的表达意图或创建一组有区别的用例。分为数字枚举和字符串枚举。

数字枚举
enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}
// Up的初始值为1,其余的成员会从1开始自动增长。Down为2,Left为3,Right为4
字符串枚举

字符串枚举并没有自增长的行为,但是可以很好的序列化。

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

函数类型

我们可以为一个函数的返回值设定类型

function sum(a: number, b: number): number {
    return a + b
}
sum(1, 2)
// 我们为sum函数的两个参数设定为number类型,返回结果也设定位number类型
可选参数和默认参数

在TypeScript中我们可以在参数名旁使用?实现可选参数的功能,可选参数和默认参数必须跟在必须在最后

// 可选参数
function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

// 默认参数
function buildName(firstName: string, lastName:string = "xm") {
    // ...
}

任意类型any

任意类型我们也可以成它为弱类型,意思就是任意类型都可以。

let foo: any = 'string'
foo = 100
foo.bar()

隐式类型转换

在TypeScript中存在隐式类型转换,因此建议我们为每个变量都添加明确的类型。

let age = 18   // number
age = 'string' // 报错

let foo        // 不声明类型
foo = 100      // 默认为任意类型any
foo = 'string' // 不报错

类型断言

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构,没有运行时的影响,只是在编译阶段起作用。就好比我们告诉TypeScript,相信我,我知道这个变量的类型是什么,我知道自己正在干什么。

// 假定这个 nums 来自一个明确的接口
const nums = [110, 120, 119, 112]
const res = nums.find(i => i > 0)
const square = res * res // 在这里会报错,因为TypeScript不确定res的类型是什么,const res: number | undefined

// 使用类型断言 两种方式是一样的
const num1 = res as number
const num2 = <number>res  // 这种方式在JSX下不能使用

接口interface

定义一些结构,我们去使用这个接口就必须去遵守这些接口所定义的结构。

interface Post {
  title: string
  content?: string  // ?代表可选成员
  readonlys summary: string // 只读属性
}

function printPost (post: Post) {
  console.log(post.title)
  console.log(post.content)
}

printPost({
  title: 'Hello TypeScript',
  content: 'A javascript superset'// 可选
  summary: 'hello'  // 只读无法修改
})

// 动态成员
interface Cache {
  [prop: string]: string 
}

const cache: Cache = {}

cache.foo = 'value1'
cache.bar = 'value2'

类class

class Person {
    // 类的属性需要使用的话,需要明确声明类型
    name: string
    age: number
    
    constructor (name: string, age: number) {
        this.name = name
        this.age = age
    }
	sayHi (msy: string): void {
        console.log(`我是${this.name},${msg}`)
    }
    
}

类的访问修饰符

  • 默认为public公共属性
  • private是私有属性,外部无法访问
  • protected受保护的,与private很相似,外部也无法访问,但是在派生类中可以被访问
  • readonly只读属性
  • 构造函数也可以被设置为private、protected
class Person {
    private name: string
    protected readonly age: number
    
    constructor (name: string, age: number) {
        this.name = name
        this.age = age
    }
	sayHi (msy: string): void {
        console.log(`我是${this.name},${msg}`)
    }
    
}

类和接口

interface Eat {
    eat(foot: string): void
}
interface Run {
    run(distance: number): void
}
class Person implements Eat, Run {
    eat(food: string): void {

    }
    run(distance: number): void {

    }
}
class Animal implements Eat {
    eat(food: string): void {

    }
}

抽象类

抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
    // 抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
    abstract run (distance: number): void
}

泛型

function createNumberArray(length: number, value: number): number[] {
    const arr = Array<number>(length).fill(value)
    return arr
}
// 上面这个函数只能创建数字类型的数组,我们要是想要创建一个字符串类型的数组,又得写一个函数,这时候我们可以使用泛型
function createArray<T>(length: number, value: T): T[] {
    const arr = Array<T>(length).fill(value)
    return arr
}
const res = createNumberArray(3, 100)
const numArr = createArray(3, 'you')
const strArr = createArray(3, 100)

类型声明

import { camelCase } from 'lodash'

declare function camelCase (input: string): string

const res = camelCase('hello typed')

// 也可以使用npm install @types/lodash --dev 添加类型声明模块

历史文章传送门

  • 大前端进击之路(一)函数式编程
  • 大前端进击之路(二)JS异步编程
  • 大前端进击之路(番外篇)手写Promise
  • 大前端进击之路(三)ECMAScript新特性

参考

拉勾大前端训练营


本文链接: http://www.dtmao.cc/news_show_600354.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?