JS和TS都有的类型
number类型
数字类型是我们开发中经常使用的类型,TypeScript和JavaScript一样,不区分整数类型(int)和浮点型(double),统一为number类型。
ES6新增了二进制和八进制的表示方法,而TypeScript也是支持二进制、八进制、十六进制的表示:
let num:number = 123
num=2
num=0b1101 //二进制
num=0o555 //八进制
num=0xf23 //十六进制
boolean类型
和JS一样,TS的boolean类型只有true/false两个值。
let flag:boolean = true
flag=20>30
string类型
string类型是字符串类型,可以使用单引号或者双引号表示:
let message:string = 'hello js'
message = "hello ts"
同时也支持ES6的模板字符串来拼接变量和字符串:
let hobby1:string="唱"
let hobby2="跳"
let hobby3="rap"
let hobbies=`my hobbies are ${hobby1},${hobby2},${hobby3}`
Array类型
数组里的元素类型可以通过以下两种方法声明:
let nums1: number[] = [1, 2, 3, 4]
let string1: Array<string> = ["ts","js"] //Array<string>事实上是一种泛型的写法
object类型
根据类型推导可以推测出student以及其属性的类型。
如果不是使用类型推导而是直接通过student:object声明student是个对象类型后,我们不能获取student内数据,也不能设置数据:
null&undefined
在 JavaScript 中,undefined 和 null 是两个基本数据类型。
在TypeScript中,它们各自的类型也是undefined和null,也就意味着它们既是实际的值,也是自己的类型
值得一提的是null和undefined在非严格模式下可以赋值给string、number等类型的变量。但是如果let n:null
则表示n有且只有一个值那就是null
Symbol类型
在ES5中,如果我们是不可以在对象中添加相同的属性名称的,比如下面的做法:
但是我们也可以通过symbol来定义相同的名称,因为Symbol函数返回的是不同的值:
TS添加的数据类型
any类型
在某些情况下,我们确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候我们可以使用any类型。
any类型有点像一种讨巧的TypeScript手段:
-
我们可以对any类型的变量进行任何的操作,包括获取不存在的属性、方法;
-
我们给一个any类型的变量赋值任何的值,比如数字、字符串的值;
如果对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候 我们可以使用any, 包括在Vue源码中,也会使用到any来进行某些类型的适配;
unknow类型
unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量。
// unknown类型只能赋值给any和unknown类型
// any类型可以赋值给任意类型
let flag = true
let result: unknown // 最好不要使用any
if (flag) {
result = foo()
} else {
result = bar()
}
unknown类型只能赋值给any和unknown类型, any类型可以赋值给任意类型
void类型
void通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型: 我们可以将null和undefined赋值给void类型,也就是函数可以返回null或者undefined。
never类型
never 表示永远不会发生值的类型,比如一个函数是一个死循环或者抛出一个异常,所以不会有返回值,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型;
function handleMessage(message: string | number | boolean | any[]) {
switch (typeof message) {
case "string":
console.log("string处理方式处理message");
break;
case "number":
console.log("number处理方式处理message");
break;
case "boolean":
console.log("boolean处理方式处理message");
break;
default:
const check: never = message;
}
}
就比如上面代码如果在联合类型添加一个any[]的数组类型,但是没有在switch语句加入对应的逻辑代码,那么就会跳到default,那么在编译过程中check:never这行就会报错,应为never类型的变量是不可能有赋值操作的。这样就起到了一个避免bug的作用。
tuple类型
tuple是元组类型,很多语言中也有这种数据类型,比如Python、Swift等。
那么tuple和数组有什么区别呢?
-
首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组中)
-
其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型;
const arr:any[] = ["jk", 18, 1.88]
const name = info[0]
console.log(name.length) //name是any类型,虽然info[0]是个字符串也能够使用name.length,
//但是其他元素就不一定了,随意调取any类型的length属性,是十分危险的。
const info: [string, number, number] = ["jk", 18, 1.88]
const name = info[0] //name是string类型,可以放心调取length属性。
console.log(name.length)
比如react的useState这个hook返回值就是一个数组,arr[0]是any类型,arr[1]是个函数并且没有返回值。这个时候使用元组就十分合适。
function useState(state: any) {
let currentState = state
const changeState = (newState: any) => {
currentState = newState
}
const tuple: [any, (newState: any) => void] = [currentState, changeState]
return tuple
}
const [counter, setCounter] = useState(10);
setCounter(1000)
const [title, setTitle] = useState("abc")