LOADING

TypeScript 变量基本类型

🍦 基本类型

-类型声明

  • 类型声明是TS中的一个非常重要的特点
  • 同过类型声明可以指定TS中的变量(参数、形参)的类型
  • 指定类型之后,当为变量赋值的时候,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错,简而言之,类型声明给变量申明了类型,就能够像强类型语言那样,指定类型的变量只能存储指定类型的值。

类型声明的语法:

let 变量: 类型;
let 变量: 类型 = value;
function f(参数: 类型, 参数: 类型): 类型{
    ....
}

试一试:

let kano: number = 123
console.log(kano);

结果当然是输出123了,但是如果我们之后想要把kano变量修改成'123'呢

kano = 'ddd' 
console.log(kano)

当你写下这段代码的时候,编辑器马上会给你划红线,提示你不能这么做,但是你依然可以进行编译,并输出正确的结果
但是默认情况下即使有错,但也会编译成功,除非ts设置的语法检查非常严格 (后续会说明如何设置)

另外,TS中的函数是需要考虑返回值还有参数类型和个数的

function sum(a: number, b: number): number {//最后一个number其实就是函数的返回值类型
    return a + b;
    // return a + b + 'ddd'//返回值类型不对
}

// console.log(sum(1, '2'));//编译会报错
// sum(1,2,3)//参数多了也会报错
// sum(1)//参数少了也会报错

-自动类型判断

  • TS有自动判断类型的机制
  • 当对变量的声明和赋值是同时进行的时候,TS编译器会自动判断变量的类型
  • 所以如果你的变量的声明和赋值是同时进行的,可以省略掉i类型声明
//TS自动类型设置
let d = false //当对变量的声明和赋值是同时进行的时候,TS编译器会自动判断变量的类型
// d = 123 //不能这么做

let e;//先声明再赋值的话,TS就不会自动判断了
e = 123 //可以这么做
e = false //可以这么做

-详细类型

类型示例描述
number1,-1,114.514任意数字
string'aa',"kano",模板字符串任意字符串
booleantrue,false布尔值
字面量let a: 10;限制变量的值是该字面量的值(可以理解为常量)
any*任意类型
unknown*类型安全的any
void空值(undefined)没有值或者为undefined
never没有值不能是任何值
object{name:'kano'}任意的js对象
array[1,2,3,4]任意的js数组
tuple[2,3]元素,TS新增类型,定长数组
enumenum{A,B}TS新增类型,枚举类型

number

// number
let decimal: number = 2;
let hex: number = 0x66ccff;
let binary: number = 0b1001;
let octal: number = 0o777;
let big: bigint = 100n;

字面量

字面量,可以暂时理解为常量:

//字面量,可以理解为常量
let aa: '114514';
aa = '114514'
// aa = '191981'//无法更改字面量的值

但与常量不同的是,字面量还有其他的玩法:

//可以使用 | 来连接多个类型(联合类型)
let sex: 'male' | 'female';
sex = 'male'
sex = 'female'
//sex = 'dd'//不行

当然,上面的联合类型语法也是可以用在其他地方的

let kanokano: number | string;
let kanokano1: number & string;//意思是必须同时是这两种类型,但这样写没有意义
kanokano = 1;
kanokano = '哈哈'

any

当你不想限定变量的类型时,你可以使用any摆烂:

//any
let dd: any;
dd = 111;
dd = '鸡';
dd = false;

P.S:变量没有加任何类型修饰符的情况下(且没有在定义的时候赋值),编译时默认看作any类型

但是any也不是万能的,因为any可以赋值给任意的变量,不安全

unknown

unknown是any的类型安全版本,被unknown修饰的变量不可以赋值给已经确定类型了的变量
但是其他类型的变量可以赋值给unknown修饰的变量
简而言之就是,你可以改变自己,但不可以改变别人(忽然哲学

let un: unknown;
let str: string;
un = 123;
str = '123';
// str = un; //不能赋值
str = un as string //类型断言
un = str;//可以赋值 
if(typeof un === 'string'){
    console.log('un变量是string类型的')
}

上面提到了 类型断言 功能,意思是告诉解析器,un是string类型的,下方细说

类型断言

类型断言:可以用来告诉解析器变量的实际类型

语法变量 as 类型 或者 <类型>变量

let dy: unknown;
let str2: number;
dy = 123;
// str2 = dy as number;
str2 = <number>dy;

看上去非常像强类型语言里面的泛型 or 强制转换,其实不然,让我们看下面的例子

let dy: unknown;
let str2: number;
dy = 'ddd';
str2 = dy as number;
// str2 = <number>dy;
console.log(str2)

上面执行没有问题,输出ddd,这是因为类型断言只是在欺骗编译器,让编译器误认为可以编译通过
这一点是区别于强制类型转换的

void

如果函数的返回值没有意义的话,可以用void来修饰返回值,return的时候可以写null也可以写undefined

//可以返回undefined或者null
function fn1(): void{
    return null
}

never

一个函数如果返回值用never修饰的话,就不能有任何return了,但是可以在函数体内抛出异常
当这个函数被调用的时候,就会抛出一个异常:

//不能有return ,用never修饰函数就是专门用来抛出错误的
function fn2(): never{
    throw new Error('这是一个报错');
}

object

首先说明一下,object修饰符实际开发中很少使用,因为它不能明确的指定是对象还是其他的引用类型

let obj: object;
obj = {}
obj = () => null

但是有一个更好用的对象修饰符 {}
{}用来指定对象中的必选属性、属性类型
语法:{属性名:属性类型}
可选属性:{属性名?:属性类型}
下面表示obj2是一个对象,属性值a是必选,age是可选,

let obj2:{a:string,age?:number}
obj2= {a:'dd'}

但上面的对象并不能支持任意多个属性的清空,所以我们还可以使用索引签名让对象开放任意个数的属性限制

//propName:string 表示属性名为string类型,这里可以选 string number或者symbol或者模板文本类型
let obj3:{b:string,[propName:string]:any}
obj3 = {b:'dd',c:'23',d:123}

函数类型

如果你希望一个变量只能保存函数的话,可以这么写
设置函数结构的类型声明

语法 (形参:类型,形参1:类型,....) => 返回值

let d2: (a: number, b: number) => number //变量名是什么无所谓
d2 = function (n1, n2): number {
    return n1 + n2
}

数组

TS中,我们可以声明一个类型确定的数组,以便于存放固定类型的值

let ee: string[]
ee  = ['1','a',"hello"]
let num: number[]
num = [1,2,3,4,5,6]
//这种写法也是可以的
let kano11:Array<number>

元组

其实就是固定长度的数组

let hh: [string, string]
hh = ['111', 'ddd']

枚举类型

和其他语言的枚举基本一样

enum Gender {
    Male,
    Female
}
//使用枚举就可以方便代码管理者,不用去特意知道男是1还是女是1了
let i: { name: string, gender: Gender }
i = {
    name: 'kano',
    gender: Gender.Female
}

类型的别名

我们可以给预定义的类型起一个自己的别名

type myType = string;
type myType2 = 1|2|3;
let k: myType;
let l: 1|2|3;
let m: myType2;
l = 1 //正确
//l = 4 //错误

补充

在字面量小结有提到 let kanokano1: number & string这段代码,这段代码是没有意义的,因为变量不可能同时是number类型和string类型,那这个& 符号有什么用呢?其实可以这样用:

let jj: {name:string} & {gender:Gender}
jj = {name: 'kano',gender: Gender.Female}

上面的jj对象,可以链接两个对象类型,意思是必须要有name和gender属性

    发表回复

    电子邮件地址不会被公开。必填项已用 * 标注