本文主要是介绍手拉手带你掌握TS数据类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
概述
TS为什么会出现呢?Coderwhy老师说的一句话我非常赞同 – 任何新技术的出现都是为了解决原有技术的某个痛点。那TS的出现是为了解决什么呢?答案当然是为了解决JS的缺陷,我们知道JS有不少的缺陷,例如:
- ES5以及之前的使用var关键字关于作用域的问题
- 最初JS设计的数组类型并不是连续的内存空间
- 直到今天JS也没有加入类型检测这一机制
而TS的出现就是解决JS的这些痛点的。
那什么是TS呢?我们来看一下 TypeScript在GitHub GitHub 和 官方上对自己的定义: - GitHub 说法: TypeScript is a superset of JavaScript that compiles to clean TypeScript output
- TypeScript 官网: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
翻译一下: TypeScript 是拥有类型的JavaScript 超集 ,它可以编译成普通、干净、完整的JavaScript 代码
怎么理解上面的话呢?
- 我们可以将TypeScript 理解成加强版的JavaScript 。
- JavaScript 所拥有的特性,TypeScript 全部都是支持的 ,并且它紧随ECMAScript 的标准,所以 ES6 、ES7 、ES8等新语法标准,它都是支持的;
- TypeScript 在实现新特性的同时,总是保持和 ES 标准的同步甚至是领先;
- 并且在语言层面上, 不仅增加了类型约束,而且包括一些语法的扩展比如枚举( Enum )、元组类型( TupleTuple )等 ;
- 并且TypeScript 最终会被编译成JavaScript代码 ,所以你并不需要担心它的兼容性问题,在编译时也可以借助于 Babel这样的工具 ;
所以,我们可把TypeScript 理解成更加强大的JavaScript ,不仅让JavaScript更加安全,而且给他带来了诸多的好用特性。
这里有一张图可以更加直观的带你理解JS和TS的关系
TS数据类型
接下来进入到本篇文章的正题,这部分将从两方面着手讲述:
- TS和JS共有的数据类型
- TS独有的数据类型
需要说明一点的就是TS中声明的数据类型要注意大小写的区别。 例如,你想要定义一个数字类型的变量: 要写成 let num: number = 3 而不是 let num: Number = 3;虽然第二种写法从语法上来说也没有问题,但是Number并不是TS的基本数据类型,他是数字类型的包装类,而诸如 ‘number’ ,‘object’, ‘boolean’, ‘string’ 等才是TS的基本数据类型。
接下来就分别来讲述吧
TS和JS共有的数据类型
说明: 单独的 export {}
并不需要导出任何东西,但它会告诉TS编译器这个文件是一个模块,不是一个全局文件,从而,在另一个文件中定义相同的变量不会产生命名冲突。
number
let num: number = 3
console.log(num)export {}
boolean
let bool: boolean = true
console.log(bool)export {}
string
let str: string= 'string'
console.log(str)export {}
Array
TS中数组定义有两种方式,一种是常规写法,另一种是泛型写法
// 常规写法
let arr1: string[] = ['a', 'b']
// 泛型写法
let arr2: Array<number> = [1,3,2]export {}
Object
这个例子用到了类型声明type,具体可以看我的另一篇文章
type InfoType = {name: 'string',age: number
}let info: InfoType = {name: 'Machigen',age: 21
}export {}
object类型可以用来描述一个对象:
const info: object = {name: 'wanger',age: 21
}// 下面的代码有问题
info['name'] = 'Q'
console.log(info.age)export {}
但是这种定义方式导致定义的对象为空对象类型,所以,不能获取数据,也不能设置数据。 例如,上面的代码会报错。
Symbol
可以通过 symbol来定义相同的名称,因为Symbol函数返回的是不同值:
const s1: symbol = Symbol('name')
const s2: symbol = Symbol('name')const person = {[s1]: 'Lee',[s2]: 'Jay'
}export {}
null 和 undefined
在TS中,这两个类型和值等同
let n: null = null
let un: undefined = undefinedexport {}
函数
function foo(num: number): string {return 'I am number ' + num
}
foo(3)// 匿名函数不建议指定类型
const names: string[] = ['Lee', 'Kobe']
names.forEach((item, index, arr) => {console.log(item, index, arr)
})export {}
匿名函数不建议指定类型 , 如上例,TS会根据forEach函数的类型推断出item,index和arr的类型,这个过程称之为上下文类型,因为函数的上下文可以帮助确定参数和返回值的类型。
对象类型
type PointType = {x: number,y: number
}function getCoordinate(point: PointType) {console.log('坐标是:(' + point.x + ',' + point.y + ')')
}
getCoordinate({ x: 2, y: 1})export {}
可选类型
对象类型也可以指定哪些类型是可选的,可以在属性的后面加一个?:
type PointType = {x: number,y: number,z?: number
}function getCoordinate(point: PointType) {console.log('坐标是:(' + point.x + ',' + point.y + ')')if(point.z)console.log('z轴是:', point.z)
}
getCoordinate({ x: 2, y: 1})
getCoordinate({ x: 2, y: 1, z: 3})export {}
TS独有的数据类型
any
使用any类型,也就间接的把TS当成JS来用了
let a: any = 123
a = 'str'
a = {}export {}
unknown
unknown 是TypeScript中比较特殊的一种类型,它用于描述不确定的变量。和any 类型有点似,但是 unknown 类型的值上做任何事情都是不合法的,必须进行类型缩小才能进一步操作
function foo(): string {return 'foo'
}function bar(): number {return 123
}const flag = true
const result: unknown;
if(flag) {result = foo()
} else {result = bar()
}// unknown类型默认情况下在上面进行任意的操作都是非法的
// 要求必须进行类型的校验(缩小)
// 才能根据缩小之后的类型, 进行对应的操作
if (typeof result === "string") { // 类型缩小console.log(result.length, result.split(" "))
}// 直接输出下面的代码会报错
console.log(result.length, result.split(" "))export {}
void
// 1.在TS中如果一个函数没有任何的返回值, 那么返回值的类型就是void类型
// 2.如果返回值是void类型,
// 那么我们也可以返回undefined(TS编译器允许这样做而已)
function sum(num1: number, num2: number): void {console.log(num1 + num2)// return 123 错误的做法
}// 应用场景: 用来指定函数类型的返回值是void
type LyricInfoType = { time: number, text: string }
// parseLyric函数的数据类型: (lyric: string) => LyricInfoType[]
function parseLyric(lyric: string): LyricInfoType[] {const lyricInfos: LyricInfoType[] = []// 解析return lyricInfos
}// parseLyric => 函数/对象
type FooType = () => void
const foo: FooType = () => {}// 1.定义要求传入的函数的类型
type ExecFnType = (...args: any[]) => void// 2.定义一个函数, 并且接收的参数也是一个函数
// 而且这个函数的类型必须是ExecFnType
function delayExecFn(fn: ExecFnType) {setTimeout(() => {fn("why", 18)}, 1000);
}// 3.执行上面函数, 并且传入一个匿名函数
delayExecFn((name, age) => {console.log(name, age)
})export {}
never
never 表示永远不会发生值的类型。比如一个函数:
- 如果一个函数中是死循环或者抛出异常,那么这会返回东西吗?
- 不会,那么写 void 类型或者其他作为返回值都不合适, 我们就可以使用 never类型
可能有些抽象,我们一起来看个应用案例吧,其中用到了联合类型,具体可以看我的另一篇文章
// 一. 实际开发中只有进行类型推导时, 可能会自动推导出来是never类型
// 但是很少使用它
// 1.一个函数是死循环
// function foo(): never {
// // while(true) {
// // console.log("-----")
// // }
// throw new Error("1233")
// }
// foo()// 2.返回一个空数组的函数
// bar函数的类型为:never[]
function bar() {return []
}// 二. 封装框架/工具库的时候可以使用一下never
// 其他时候在扩展工具的时候, 对于一些没有处理的case, 可以直接报错
function handleMessage(message: string | number | boolean) {switch (typeof message) {case "string":console.log(message.length)breakcase "number":console.log(message)break
// case "boolean":
// console.log(Number(message))
// breakdefault:const check: never = message}
}handleMessage("aaaa")
handleMessage(1234)// 此时switch分支的default会报错,必须加上'boolean'的判断情况才行
handleMessage(true)export {}
tuple
// 保存个人信息: kobe 18 1.88
// 1.使用数组类型
// 不合适: 数组中最好存放相同的数据类型, 获取值之后不能明确的知道对应的数据类型
const info1: any[] = ["kobe", 18, 1.88]
const value = info1[2]
console.log()// 2.使用对象类型(最多)
const info2 = {name: "why",age: 18,height: 1.88
}// 3.使用元组类型
// 元组数据结构中可以存放不同的数据类型, 取出来的item也是有明确的类型
const info3: [string, number, number] = ["why", 18, 1.88]
const value2 = info3[2]// 在函数中使用元组类型是最多的(函数的返回值)
function useState(initialState: number): [number, (newValue: number) => void] {let stateValue = initialStatefunction setValue(newValue: number) {stateValue = newValue}return [stateValue, setValue]
}const [count, setCount] = useState(10)
console.log(count)
setCount(100)export {}
可以看出,元组与数组有些类似,那么tuple和数组有什么区别呢?
- 首先, 数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中 。(可以放在对象或者元组中) 。
- 其次, 元组中每个素都有自己特性的类型 ,根据索引值获取到的值可以确定对应的类型
const info: (string|number)[] = ['coder', 25, 1.88]
const item1 = info[0] // 不能确定具体的类型,只能确定为联合类型const tupleInfo: [string, number, number] = ['coder', 25, 1.88]
const item2 = info[0] // 类型一定是stringexport {}
总结
本篇文章我们讲述了TS的基本数据类型及其简单使用,下篇文章我们一起来唠唠TS语法细节哪些事。
这篇关于手拉手带你掌握TS数据类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!