TypeScript学习之旅:二、TypeScript的基本数据类型

470 阅读5分钟

前言

在上篇文章中我们了解到了 JavaScript 的一些问题;TypeScript 的出处、运行逻辑、还有能为我们带来什么等等(详情)。这篇文章主要来了解一下 TypeScript 的基本数据类型。

一、变量的定义

  • TypeScript 定义变量和 ES6 之后一致,可以使用 var、let、const 来定义 var/let/const 标识符: 数据类型 = 赋值;
var message1: string = '消息'
let message2: string = '消息'
const message3: string = '消息'

二、简单数据类型

字符型

let message: string = '消息'

数值型

let num: nunber = 20

布尔型

let boo: boolean = true

数组

const arr: number[] = [1, 2, 3, 4, 5];
const arr1: Array<number> = [1, 2, 3, 4, 5]; // Array<number> - 泛型定义

对象

const obj: {name: string; age: number} = {
    name: "张三",
    age: 18
}

type objType = { // 类型别名
    name: string,
    age: number
}
const obj1: objType = {
    name: "张三",
    age: 18
}

三、复杂数据类型

any

  • 官方解释:TypeScript 还有一个特殊类型 ,any当您不希望某个特定值导致类型检查错误时,您可以使用它。

  • any 其实就是 TypeScript 提供的一个非常特殊的类型,如果你是初次接触类型检测机制或是第一次使用 TypeSctip,对 TypeSctip 中的定义类型语法不熟悉,我们可以 '暂时' 使用 any 来代替你所需要定义的类型。不过其实不建议如此使用,因为这样做类型检测机制便会失去他本身的意义。

  • 如果定义一个变量,我们并没有指定这个变量的类型注释,那么 TypeScript 无法从上下文中推断出它的类型时,这个变量就会默认为 any。

  • 一但变量的类型是 any 时,他将适用于所有的类型的值,或者说几乎任何类型的值赋给这个变量都是合法的。

  • 基本用法

let str: any = "123"
let num: any = 123
let boo: any = true
let arr: any = [0, 1, 2]
let obj: any = {
    name: "张三",
    age: 18
}
  • 案例

这是一个较为简单的使用 TypeSript 书写的一个计算和方法 list: Array<number> 中的 Array<number> 是一个泛型,方法的返回值必须是一个 number

function funAndCalculation(list: Array<number>): number {
    let count = 0
    list.forEach(item => {
        count += item
    });
    return count
}

console.log(funAndCalculation([1, 2, 3]));

1.png

我们使用 any 来重新写一下。

function funAndCalculation(list: any): any {
  let count = 0
  list.forEach(item => {
    count += item
  });
  return count
}
console.log(funAndCalculation([1, 2, 3]));

2.png

联合类型

  • 联合类型是由两个或多个其他类型组成的类型,表示可能是这些类型中的任何一种的值

  • 开发过程中一切都不是固定的,比如我有一个方法,只需要一个参数,这个参数是 number 或是 string 都是可以的,这时我们就可以使用 | 联合类型来定义放大的参数类型

function getUserInfo(id:  number | string) {
  console.log(id)
}

getUserInfo('123')
getUserInfo(123)

  • 但是 联合类型也是有弊端的比如:及时我们传入的是字符型的参数, TypeScript 依然爆红,提示我们不存在 toUpperCase()
function getUserInfo(id:  number | string) {
  console.log(id.toUpperCase())
}

getUserInfo('1')

3.png

  • 解决方法:类型缩小机制(后续会具体来说), 我们用过 typeOf 来进行判断传入的参数类型是 string 还是 number,再去做相应的处理。
function getUserInfo(id:  number | string) {
  if(typeof id === 'string') {
    console.log(id.toUpperCase())
  }else {
    console.log(id);
  }
}

getUserInfo('a')
getUserInfo(1)

4.png

可选类型

  • TypeScript 中对象类型还可以指定其部分或全部属性是可选的。
function printPoint(point: {x: number, y: number, z?: number}) {
  console.log(point.x)
  console.log(point.y)
  console.log(point.z)
}

printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})

5.png

非空类型断言

  • 这个其实并不是 TypeScript 中的内容,在 ES6 中推出,用来判断对象是否有一个属性,可以大大的节省我们的代码量。
// message? -> undefined | string
function printMessageLength(message?: string) {
  console.log(message!.length)
}

printMessageLength("aaaa")
printMessageLength("hello world")

字面量类型

  • 官方解释:除了一般类型 stringnumber ,我们可以在类型位置引用特定的字符串和数字。

  • Hello World 也是可以作为类型的, 叫做字面量类型。官方:就其本身而言,文字类型并不是很有价值。

const message: "Hello World" = "Hello World"

let num: 123 = 123
// num = 321 // 错误:不能将类型 "321" 分配给类型 "123"

// 字面量类型的意义, 就是必须结合联合类型
type Alignment = 'left' | 'right' | 'center'

let align: Alignment = 'left'
align = 'right'
align = 'center'
// align = 'Hellow' // 错误:不能将类型 "Hellow" 分配给类型 'left' | 'right' | 'center'
  • 字面推理

字面量类型也是有类型推导的。下面的例子中 handleRequest() 函数需要两个参数 一个是 srtingurl,一个是联合类型 GET | POSTmethod,但是及时我们传入的是 GETTypeScript 依然会报错,因为 TypeScript 认为 req.method 的类型为 string,并不符合 handleRequest 所需要的类型。

const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

function handleRequest (url: string, method: "GET | POST") {
console.log('object :>> ', url, method);
}

6.png

解决方法一: 使用类型断言 as "GET | POST"

const req = { url: "https://example.com", method: "GET" as "GET | POST" };
handleRequest(req.url, req.method );

function handleRequest (url: string, method: "GET | POST") {
  console.log('object :>> ', url, method);
}

解决方法二: 使用类型断言 as const

const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method );

function handleRequest (url: string, method: "GET | POST") {
  console.log('object :>> ', url, method);
}

类型断言as

  1. 有时候TypeScript无法获取具体的类型信息,这个我们需要使用类型断言
  2. 比如我们通过 document.getElementById,TypeScript只知道该函数会返回 HTMLElement ,但并不知道它具体的类型
const el = document.getElementById("why") as HTMLImageElement
el.src = "url地址"
  1. TypeScript只允许类型断言转换为 更具体 或者 不太具体 的类型版本,此规则可防止不可能的强制转换

7.png

8.png

const name = "Hello World" as number // 会报错的的
const name = ("Hello World" as unknown) as number // 可以的

写在最后

  • 这篇主要讲述了 TypeScript 的基本数据类型,基本类型并不复杂,不过所有的复杂类型都是由基本类型堆砌而成的,只要熟练掌握基本类型,我们就可以在项目中去简单的使用 TypeScript 来开发。

  • 下一遍文章我们将讲述 TypeScript 中的 函数类型、泛型及 interfacetype