从零到一学习TypeScript(一)基本类型

1,176 阅读6分钟

搞定TypeScript

Typescript 帮助我们前端人员提高类型思维的能力,弥补类型约束的条件,减少我们开发时发生的各种类型判断的验证

我们所有 ts 代码在 webpack 环境运行

首先我们需要全局安装 ts (这里建议 npm 安装, yarn 全局安装会有问题)

安装命令
npm install typescript -g
查看版本
tsc --version
我们首先需要全局先安装typescript 如上
yarn init -y
yarn add webpack webpack-cli -D
yarn add typescript -D
// 由于我们webpack后续编译的是我们TypeScript代码,而不是tsc tsc是在全局范围中使用
// 我们需要在本地使用typescript
tsc --init // 我们在ts 开发时 需要对ts进行配置 会生成 tsconfig.json
yarn add ts-loader -D // 解析typescript代码
yarn add html-webpack-plugin -D 生成html模板

版本号 和运行命令

image.png

webpack配置

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader'
      }
    ]
  },
  // devServer: {
  // },
  resolve: {
    extensions: ['.ts', '.js']
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: 'body',
      template: './index.html'
    })
  ]
}

举个例子

目录结构

image.png

index.ts

import { sum, mul } from './learn/test'
sum(200, 300)
console.log(mul(20, 30))

export {}

test.ts

export const sum = (num1: number, num2: number): void => {
  console.log(num1 + num2);
}

export const mul = (num1:number, num2: number): number => {
  return num1 * num2
}

这样我们环境就大功告成了

image.png

在我们发生错误时 webpack中的ts都会提示 具体哪里出了问题

image.png

觉得这样太麻烦的 我们还可以使用 node环境来运行 ts-node

安装ts-node
npm install ts-node -g
ts-node 还需要依赖tslib 和 @type/node
npm install tslib @type/node -g
然后我们就可以直接使用ts-node test.js来执行文件了

1. 变量的声明

我们刚开始学习 需要在typescript定义变量的时候需要添加标识符的类型,声明了类型之后typescript就会进行类型监测 就是type annotation

我们声明一个message

const name:string = 'erkelost'

我们定义类型标识时 我们定义的数据类型都是小写 string 代表typescript 的字符串类型 我们是不能写成大写 大写就是 javascript中的类

如果我们定义了string 修改类型就会报错

image.png

image.png

typescript中不建议使用var 定义变量 var 的作用域问题 没有块级作用域 会引发其他问题

typescript中 如果我们没有给变量添加类型 ts会自动推断 给我们添加类型

image.png image.png

2. 类型

一,number类型

1.TypeScript和JavaScript一样,不区分整数类型(int)和浮点型(double),统一为number类型

image.png

2.Typescript 也支持 二进制 八进制 十六进制 和 javaScript一样

image.png

二,boolean类型 只有两个值 true false

image.png

三,string 类型 可以用es6 模板字符串

image.png

我们的obj会被自动推断成string

四, array类型

const arr: string[] = ['123', '456', 'erkelost', 'adny']

在我们定义数组类型中 最好不要数组中存在着多个不同类型,我们存放的数据类型最好的固定的而且我们如果定义string类型 就不能在向数组中push别的类型的数据

五,object类型

我们可以用type 关键字定义类型 我们还可以用接口定义对象类型 后续会写 type 和 interface

image.png

image.png

如果我们直接在类型加上object 会报错

image.png

六, symbol类型

es6之前 我们是不可以在对象中添加 相同名称的属性

image.png

但是我们可以使用es6的symbol类型 来 创建

image.png

image.png

七, null 和 undefined

null 和 undefined 是两个基本数据类型

他们各自类型的值 也是null 和 undefined

image.png

他们只能赋值 自己类型本身的值 其他报错

八, any类型

在typescript中 我们在某些情况无法确定一个变量的类型 那么我们可以给他定义成 any类型

我们可以对any类型进行任意操作 对any类型的变量赋任何的值 任何类型 都可以是any类型,如果设置了any类型的值 无需进行任何的检查

image.png

我们一般在添加过于繁琐的变量 或者数据时 可以使用 any类型

九, unknown类型

unknown 用于描述类型的 不确定变量 所有类型可以归于any类型 所有类型也可以归于unknown类型 我们如果全都使用any类型 就相当于没有使用TypeScript当中的大量监测机制

image.png

可能这样我们还是理解不了 unknown类型

unknown类型 相对于 any 更加安全

image.png

理解 any 和 unknown

所有类型 都是 any 所有类型都是 unknown

let adny: unknown
adny = true
adny = 123
adny = 'erkelost'
adny = []
adny = {}
adny = null
adny = undefined
adny = Symbol("erkelost")
let adny: any
adny = true
adny = 123
adny = 'erkelost'
adny = []
adny = {}
adny = null
adny = undefined
adny = Symbol("erkelost")

这两段代码都是可以执行的 但是 如果我们 把 unknown类型赋值给别的类型

let adny: unknown
let a: unknown = adny // true
let b: any = adny // true
let c: string = adny // false
let d: boolean = adny // false
let e: number = adny // false
let f: numm = adny // false
........
........

这说明 unknown类型只能被赋值给 unknown 和 any 类型 只有能够保存任意类型值得 变量才能保存 unknown类型 , 因为我们不知道unknown类型里面到底保存了什么值

注意: unknown类型只能赋值给any类型 和 unknown类型 但是 any类型可以赋值给任何类型 他俩的主要区别就是unknown类型会更加严格 unknown 和 any 是 TypeScript中的顶级类型

十. void类型

void 指一个函数没有返回值时 那么他的返回值 就是void类型, 我们可以将null 和 undefined 赋值给void类型 也就是函数返回null 和 undefined

image.png

如果函数没有定义返回值类型 那么默认就是返回值 就是void类型 当然我们也可以显示得指定 函数得返回值为void

image.png

十一, tuple类型

tuple是元组类型

那么元组和数组有什么区别呢

  • 1. 数组中我们推荐放置相同类型的元素

  • 2. 不同的类型的元素 不推荐放在数组里

  • 3. 我们可以把不同的类型的元素放到元组 或者 对象里

const adny: [string, number, string] = ['adny', 123654, 'erkelost']
const a = adny[0] // 能够取到对应的值 而且知道 a是 string类型
const b = adny[1] // 能够取到对应的值 而且知道 b是 number类型

所以 元组中每个元素 都有自己对应的类型 根据索引值可以获取到对应的类型

那么元组到底有什么用呢?

元组的应用场景

function usestate(state:any) {
  let currentstate = state
  const changestate = (newstate: any) {
    currentstate = newstate
  }
  const arr: any[] = [currentstate, changestate]
  return arr
}
const [counter, setcounter] = usestate(10) 

如果我们这么写的话 那么最后拿到的 counter 和 setcounter 都是 any类型 因为我们定义数组的时候就是any类型 但是我们希望 数组的第二个值 应该是一个tuple 元组类型 那么我们 就可以这么做

function usestate(state:any) {
  let currentstate = state
  const changestate = (newstate: any) {
    currentstate = newstate
  }
  const arr: [any, (newstate:any) => void] = [currentstate, changestate]
  return arr
}
const [counter, setcounter] = usestate(10) 

这样的话 拿到的setcounter 就是一个函数类型 我们就可以把他当作一个函数去使用 但是前面的counter 如果我们

const [counter, setcounter] = usestate('qwer') 

我们不管传递的参数 是什么 counter的类型都是any 这个我们可以等到学了泛型 就可以进一步优化了