第一节:TypeScript变量与数据类型

1. 变量的类型注释

在JavaScript中, 变量的复制相对灵活, 除了const外, letvar声明的变量可以赋予不同类型的数据

例如:

let val = 'string'
console.log(typeof val)
// 变量val的类型为string 类型

val = 10
console.log(typeof val)
// 变量val的类型为number 类型

val = true
console.log(typeof val)
// 变量val的类型为boolean 类型

示例中, 变量val可以赋值不同类型的变量, 而变量的类型取决于赋予变量的值.

如果我们需要限定变量的类型, 只允许给变量赋予某一种类型或几种基本类型 的联合类型, 我们就需要使用TypeScript给变量添加类型注释

1.1 赋初值

基础变量声明的语法
let [变量]:[类型注释] = 值

类型注释需要用来描述变量可以被赋予那些类型的值.

// 1. 这样会报错,声明的变量是number类型,却被赋值为string类型的值
let a:number = 'hello'

// 2. 这样也会报错,声明string类型后中途重新赋值了其他类型的值
let a:number = 20
a = 'hello'

这种方式实现的变量命名的好处,那就是在赋值的时候确定变量的类型,如果存值和声明的变量类型不符合就会报错
声明类型的变量,将只能赋予相同类型的值

如果声明变量赋初始值,在大多数情况下,添加类型注释并不是必须的, 原因在与TypeScript会根据我们赋予的初始值来自动推断变量的类型.

例如:

let a = 'hello'
// let a: string

a =  10
// 不能将类型“number”分配给类型“string”

TypeScript更加初始赋值'hello'推断变量astring类型, 此时在将其他类型数据赋值给变量a就会报错

1.2 不赋初始值

语法
let [变量]:[类型注释]

  1. 如果只创造了变量并规定类型,那么这个变量默认值就是undefined
  2. 如果后面需要赋值时,还是只能按照 声明的变量类型来赋值,否则就会出错
let num:number;
console.log(num)  // undefined

num = 10  // ok

num = 'hello'
// 错误:不能将类型“string”分配给类型“number”

声明一个变量不管什么类型, 初始不赋值,变量默认为undefined,这是遵循JavaScript的语言规范,

那么为什么undefined类型的值可以赋值给number类型的值呢? 那么先来了解一下TypeScript类型


2. 数据类型

TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

TypeScript 数据类型有:

  1. 数字类型 number
  2. 字符串类型 string
  3. 布尔类型 boolean
  4. undefined undefined
  5. null null
  6. 数组类型 []
  7. 元组 [] (数组的特殊形式)
  8. 对象类型 {}
  9. 函数类型 Function
  10. 任意类型 any
  11. void void
  12. never never
  13. unknown 不认识,代表 任何值,类似于any
  14. 枚举 enum

2.1 字符串,数字,布尔类型

和JavaScript 字符串,数字,布尔类型一样,并且所有数字都是浮点数。以及可以使用ES6字符串模板

// 字符串类型
let username = '张三'
let person :string = `字符串模板${username}`
console.log('person', person)

// 数字类型
let num: number = 30
console.log('num', num)

// 布尔类型
let bol: boolean = true;
console.log('bol',bol)


2.2 数组类型

JavaScript定义数组可以通过字面量和构造函数, TypeScript在添加数组的类型注释也不同的方式

第一种就是使用字面量的方式

// 正确的写法
let arr: number[] = [10, 20, 30, 40];

let arr: string[] = ['a', 'b', 'c', 'd'];
// ...

// 错误的写法
let arr:[number] = [10, 20, 30, 40];
// 这种写法指表示确定数组第一项的数据类型,其他的没有确定,报错

number[]这种数组类型的定义方式, 其中[]表示是数组类型,number是基本数据类型, 表示数组每一项都是number类型

第二种:使用内置的泛型Array

// 或者使用泛型
let arr: Array<number> = [10, 20, 30, 40];

let arr: Array<string> = ['a', 'b', 'c', 'd'];
// ...

上面的示例中数组内所有的值都是同一种类型, 但在很多情况下数组内会有不同数据类型的值,

那么就可以使用any类型或联合类型

使用any类型定义数组内的元素类型

let arr: any[]= [10, 'hello', true, null];
let arr: Array<any> = [10, 'hello', true, null];

// any表示任意类型,表示数组内每一项都可以是任意类型

使用联合类型数组, 联合类型使用|符合,

联合类型的前提是你明确的知道,数组内只能存那些类型的数据

例如:我们希望一个数组只能存number,string两种类型的值

let arr:(string | number)[] = ['hello' , 20, 'world']

let arr:Array<string | number> = ['hello' , 20, 'world']

(string | number)[]类型注释中[]表示为数组类型,(string | number)就是联合类型,表示数组没一项可以是string类型或number类型.满足一个即可


2.3 元组类型

元组类型其实就是另外一种Array数组 类型. 它确切的知道数组中包含多少元素, 以及它在特定位置包含哪些类型

元组类型表示一个已知元素数量和每一项类型的数组,各元素的类型不必相同

其实元祖类型就是单独定义数组的每一个数据的类型.

// 正确的写法
let arr:[number,string, boolean] = [10,'string',true]

// 错误的写法
let arr:[string,string, boolean] = [10,'string',true]
// 编译时报错,Type 'number' is not assignable to type 'string'.
// 不能将数字类型的值赋值给字符串类型

// 注意定义数据类型和数据的数量保持一致, 数量不同则会报错
let arr:[string,string, boolean] = [10,'string']
// Property '2' is missing in type '[string, number]' but required in type '[string, number, boolean]'.

也可以先声明元组类型的变量,之后再重新赋值

let a:[string,number,number,boolean,object]

// 这种 写法没问题
a =  ["hello",1,2,true,{age: 18}];

// 这种写法不行,上面创建变量时,要求的类型和值的类型按照顺序对不上
a = [1, "hello" , 2, true,{age: 18}];

// 这个写法也不可以,因为少了一个对象
a = ["hello",1,2, true];

TypeScriptde的一个好处就是,会在代码执行前的类型检查阶段抛出错误, 不想JavaScript只能在代码运行时,才知道发生了什么错误


2.4 object 引用数据类型

object是一个特殊的类型, 指定是任何不是原始值(string, number,bigint,boolean,symbol,null, undefined)的值.

这与空对象类型{}不同, 也与全局类型Object不同

object表示的是JavaScript中的引用类型,只要是具有属性的类型都可以使用object类型

// 函数
const fn:object = () => console.log('fn')

// 数组
const arr:object = [10,20]

// 对象
const obj:object = {name:'hello', age:18}

因此这个类型在使用很少, 大多通过更详细的类型添加类型注释.

例如:

// 函数类型注释
const fn:() => void = () => console.log('fn')

// 数组类型注释
const arr:number[] = [10,20]

// 对象
const obj:{name:string,age:number} = {name:'hello', age:18}


2.5 对象类型

除了基本数据类型, 最常见的类型是对象类型. 对象类型是值任何带有属性的JavaScript值

对象类型几乎是所有的属性都要定义对象类型.

通过关键字object定义对象类型

// 对象类型
let ob:object =  { a: 10 }

这种类型注释的对象并不限定属性数量与属性值的类型. 可以赋值任意类型

也可以通过字面量方式,列出所有属性以及属性类型来进行类型注释

let student:{name:string,age:number} = {name:'张三',age:18}


2.6 Function 类型

Function为全局类型, 描述JavaScript中所有函数值的属性, Function类型总是可以调用类型值的特殊属性, 这些调用返回any, 一般也不常用

function example(fn:Function){
    return fn(1,2)
}

参数fn是一个具有函数属性的函数类型, fn()的调用是一个无类型的函数调用, 因为返回类型为any类型不太安全.最好避免使用,.

可以使用更加详细的函数类型注释

例如:

function example(fn:() => void){
    return fn(1,2)
}


2.7 任意类型 any

TypeScript也有一个特殊的类型: any类型,当你不希望某个特定的值导致类型检查错误时,可以使用它

通常当你声明一个变量, 没有确定初始类型,也没有赋初始值是,或者赋初值为undefined或null时, 变量的类型默认为any类型.

也就是说:当您不指定类型,并且 TypeScript 无法从上下文中推断出它时,编译器通常会默认为any.

any类型的变量赋值任何类型的数据都不会报错

let a = null
// 或者
let a = undefined
// 或者
let a;
// let a: any

a = 'aa'
console.log(a) // 'aa'
a = 30
console.log(a) // 30

一般来说并不建议大量使用any类型.当你明确知道一个变量之后不会被赋予其他类型的数据, 那么就可以在声明变量时添加详细的类型注释;

只有当你在不确定变量未来会赋予什么样类型的值时, 可以尝试使用

注意:

any类型的变量会跳过类型检查

例如:

let obj: any = { x: 0 };

// 下面代码将没有一行代码编译错误
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;

实例中变量objany类型, 因此obj身上的所有操作都会跳过类型检查, 因此在TypeScript编译代码时不会报错.

但是执行编译后的代码可能会出错.

2.8 空类型 void undefined null

Void 表示没有任何类型 空
通常声明一个Void 类型没什么意义,因为这个类型的变量只能赋值为undefined和null

let a: void = undefined;
console.log(a)

let a: void = null;
console.log(a)

// 赋值其他类型的值就会报错
let a: void = 123;
console.log(a)
// 报错:不能将类型“number”分配给类型“void”

在TypeScript里,undefined和null 两者各自都有自己类型分别叫做undefined和null;和void相似,他们的类型本身用处不大:

// 声明一个undefined类型变量
let und: undefined;
und = undefined;
und = null;
console.log(und)

// 声明一个null类型的变量
let nul: null
nul = null;
und = undefined;
console.log(nul)

void一样, undefinednull类型只能赋值undefinednull值, 本身意义不大

默认情况下,null和undefined 是 所有类型的子类型
就是说你可以把null和undefined赋值给其他类型的变量

let num:number = undefined;
let num:number = null;
let str:string = undefined;
// ....

但是,不能将其他类型的值赋值给void,undefined,null类型的变量

let un:undefined =  12;
let aa:null = 'aa';
let bb:void = true;

这样写会报错

2.9 never类型

never类型表示的是那些永不存在的值的类型
这个严格来说算不上新的数据类型,只是开发者对于一些值所起的作用的判断而已

比如:

  1. 总是会抛出异常,throw错误或是返回一个error类型的数据
  2. 根本就不会有返回值的函数表达式(死循环函数)
// 没有返回值
function error(msg:string):never {
  throw new Error(msg)
}

// 一旦有了返回值never类型就报错
function error():never {
  retrun new Error('something failed')
}
// 报错: 不能将类型“Error”分配给类型“never”。

// 哪怕没有显示的return 也会报错, 因为函数有默认返回undefined
function error():never {
  new Error('something failed')
}
// 返回“never”的函数不能具有可访问的终结点。


// 死循环函数
function infiniteLoop():never{
  while(true){
    console.log('帅")
  }
}

never类型是任何类型的子类型,任何其他类型的值都不能赋值给never类型.即使any也不可以

let n:never;
n = 12
// 不能将类型“number”分配给类型“never”


2.10 unknown 类型

unknown类型代表任何值, 这类似于any类型, 但更安全, 因为用值做任何事情都是不合法的

例如:

function fn1(a:any){
    // 调用any类型的属性是合法的
    // 任意类型有可能是对象类型
    a.b()
}


function fn2(a:unknown){
    // unknown 未知类型, 不确定它是什么值
    a.b()
    // 报错:类型“unknown”上不存在属性“b”。
}


2.11 枚举类型

枚举类型是TypeScript添加到JavaScript的一项功能, 它允许描述一个值, 该值可能是一组可能的命名常量之一.

与大多数TypeScript功能不同,这不是对JavaScript的类型级添加, 而是添加到语言和运行时的东西.

详细内容稍后章节介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容