一,TS的数据类型

ES6的数据类型:

6种基本数据类型

	Boolean
Number
String
Symbol
undefined
null

3种引用类型

	Array
Function
Object
TS的数据类型:

TS在ES6基础上,又新增了以下数据类型

	void
any
never
元组
枚举
高级类型

除此之外,TS还有很多类型的高级使用技巧


二,类型注解

TS可以通过类型注解对变量类型进行约束
TS和JS最主要的区别:变量的数据类型不可改变 语法: 变量/函数 : type 如: let hello : string = 'Hello TypeScript'

三,原始类型

let bl: boolean = true
let num: number = 123
let str: string = "123"

使用类型注解对变量进行类型约束后,再进行不恰当的赋值就会报错


四,数组类型

在 TypeScript 中,数组类型有多种定义方式,主要有一下三种定义方法:

1、「类型 + 方括号」表示法

let  tsArray: number[] = [1,1,2,3,4]

  数组中的项中不允许出现其他类型

let fibonacci: number[] = [1, '1', 2, 3, 5];
//报错

  上例中,[1, '1', 2, 3, 5] 的类型被推断为 (number | string)[],这是联合类型和数组的结合。

 数组的一些方法的参数也会根据数组在定义时约定的类型进行限制:

let fibonacci: number[] = [0, 1, 2, 3, 5];
fibonacci.push('6');
// index.ts(2,16): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

  上例中,push 方法只允许传入 number 类型的参数,但是却传了一个 string 类型的参数,所以报错了。 

2、数组泛型 

 使用数组泛型(Array Generic) Array<elemType> 来表示数组:  

let arrType: Array<number> = [0, 1, 2, 3, 5];
let arrType1: Array<string> = ['0', '1', '2', '3', '5'];
let arrType2: Array<any> = [1, '1', 2, 's', true];

3、用接口表示数组

interface Person{
name: string;
age: number;
}
interface NumberArray {
[index:number]: Person;
}
let arrType3: NumberArray = [{name:'张三',age: 20}]
let arrType4:Array<Person> = [{name:'张三',age: 20}]
let arrType5:Person[] = [{name:'张三',age: 20}]

 NumberArray 表示:只要 index 的类型是 number,那么值的结构类型必须是符合Person接口。

  类数组(特别注意)

    类数组(Array-like Object)不是数组类型,比如 arguments

function sum() {
let args: number[] = arguments;
} // index.ts(2,7): error TS2322: Type 'IArguments' is not assignable to type 'number[]'.
// Property 'push' is missing in type 'IArguments'.

  事实上常见的类数组都有自己的接口定义,如 IArgumentsNodeListHTMLCollection 等:

function sum() {
let args: IArguments = arguments;
}

五,元组类型

是一种限制数组的元素类型和个数的数组
let tuple: [number, string] = [0, '1']

此时,如果改变数组的元素类型或添加元素数量,编辑器都会报错:

let tuple: [number, string] = [0, 1]
//Type 'number' is not assignable to type 'string'. let tuple: [number, string] = [0, '1', '2'] //报错:
Type '[number, string, string]' is not assignable to type '[number, string]'.
Types of property 'length' are incompatible.
Type '3' is not assignable to type '2'.
元组越界问题:

虽然元组限制了数组元素的类型和数量,过多的元素声明会报错
但TS允许向元组中使用数组的push方法插入新元素(但不允许访问)

let tuple: [number, string] = [0, '1']
tuple.push(2)
console.log("tuple.push(2)", tuple) // tuple.push(2) (3) [0, "1", 2]

但不允许访问:

tuple.push(2)    // 可越界添加
tuple[2] // 不可越界访问 //报错:
//Tuple type '[number, string]' of length '2' has no element at index '2'.

六,函数

  在 JavaScript 中,有两种常见的定义函数的方式——函数声明(Function Declaration)和函数表达式(Function Expression):

// 函数声明(Function Declaration)
function sum(x, y) {
return x + y;
} // 函数表达式(Function Expression)
let mySum = function (x, y) {
return x + y;
};

1、函数声明

一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:

function sum(x:number,y:number):number{
return x+y
}

注意,输入多余的或者少于要求的参数,是不被允许的

sum(1, 2, 3);

// index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
sum(1);

// index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.

2、函数表达式

  如果要我们现在写一个对函数表达式(Function Expression)的定义,可能会写成这样

let mySun = function(x:number,y:number):number{
return x + y
}

这是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 mySum,是通过赋值操作进行类型推论而推断出来的。如果需要我们手动给 mySum 添加类型,则应该是这样:

let mySum(x:number,y:number)=>number = function(x:number,y:number):number{
  return x+y}

注意不要混淆了 TypeScript 中的 => 和 ES6 中的 =>

在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。

在 ES6 中,=> 叫做箭头函数,应用十分广泛,

3、用接口定义函数的形状

我们也可以使用接口的方式来定义一个函数需要符合的形状:

interface SearchFunc{
(source:string,subString:string):boolean
} let mySearch:SearchFunc;
mySearch = function(source: string,subString:string){
return source.search(subString) !== -1
}

函数入参

1、可选参数

前面提到,输入多余的(或者少于要求的)参数,是不允许的。那么如何定义可选的参数呢?

与接口中的可选属性类似,我们用 ? 表示可选的参数:

function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

注意:可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必须参数了

2、参数默认值

在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:

function buildName(firstName:string,lastName:string='Cat'){
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

此时就不受「可选参数必须接在必需参数后面」的限制了:

function buildName(firstName: string = 'Tom', lastName: string) {
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName(undefined, 'Cat');

3、剩余参数 

 ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数):

function push(array,...items){
items.forEach(function(item){
array.push(item)
  })
} let a = [];
push(a,1,2,3)

事实上,items 是一个数组。所以我们可以用数组的类型来定义它:

function push(array:any[],...items:any[]){
items.forEach(function(item){
array.push(item);
})
} let a = []
push(a,1,2,3)

注意:rest 参数只能是最后一个参数

重载:

重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

比如,我们需要实现一个函数 reverse,输入数字 123 的时候,输出反转的数字 321,输入字符串 'hello' 的时候,输出反转的字符串 'olleh'

利用联合类型,我们可以这么实现:

function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}

然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。

这时,我们可以使用重载定义多个 reverse 的函数类型:

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}

上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。

注意:TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。

 

七,对象

在JS中,可以任意修改对象属性,TS中不允许

let obj: object = {x: 'a', y: 'b'}
obj.x = 3 // Property 'x' does not exist on type 'object'.
这是因为,仅声明了对象obj的类型注解是object,
并没有为对象内部的具体属性(属性名)和类型做限制
let obj: {x: string, y: string} = {x: 'a', y: 'b'}
obj.x = 'c'

还可以使用接口的形式来规范对象,接口会在下一篇随笔介绍。


八,Symbol

	具有唯一的值
可以显式声明,也可直接创建
let symbol1: Symbol = Symbol()  // 显示声明
let symbol2 = Symbol() // 直接创建 // 验证:是否是同一个对象
console.log(symbol1 === symbol2) // fasle

九,undefined 和 null

let udf: undefined = undefined
let nu: null = null
一旦声明了undefined,就不能再被赋值为任何其他的数据类型了:
let undf: undefined = 1
// Type '1' is not assignable to type 'undefined'.
默认情况下,undefined和null也不能被赋值给任何其他类型:
// 验证:undefined和null也能被赋值给任何其他类型

let num1: number = undefined
// Type 'undefined' is not assignable to type 'number'. let num2: number = null
// Type 'null' is not assignable to type 'number'.
允许undefined和null被赋值其他类型:
在TS中,undefined和null是任何类型的子类型,所以可以被赋值给其他类型

设置允许被赋值为其他类型

打开tsconfig.js,将strictNullChecks = false(默认true)

在不修改此配置的情况下,实现对undefined和null的赋值,可使用联合类型
let num3: number | undefined | null = 111

十,void

在js中,void操作符可以使任何一个表达式返回undefined

	void 0 	// 将返回undefined

在TS中,void类型表示没有返回值,没有返回值的函数,他的类型就是void类型

// void
let voidFunc = () => {}

十一,any

any:如果不指定TS的变量类型,默认为any类型,可以赋值为任何类型
let x
x = 1 // 整型
x = [] // 数组
x = () => {} // 函数
不建议使用any类型,将失去使用ts的意义

十二,never

never:永远不会有返回值的类型

1,函数抛出异常,永远不会有返回值,类型为never

// 函数抛出异常,永远不会有返回值,类型为never
let error = () => {
throw new Error('error')
}

2,死循环函数永远没有返回值,类型为never

// 死循环函数永远没有返回值,类型为never
let endless = () => {
while(true) {}
}

TypeScript——02——TS基本数据类型介绍和使用的更多相关文章

  1. Typescript 学习笔记一:介绍、安装、编译

    前言 整理了一下 Typescript 的学习笔记,方便后期遗忘某个知识点的时候,快速回忆. 为了避免凌乱,用 gitbook 结合 marketdown 整理的. github地址是:ts-gitb ...

  2. 学习TypeScript,笔记一:TypeScript的简介与数据类型

    该文章用于督促自己学习TypeScript,作为学笔记进行保存,如果有错误的地方欢迎指正 2019-03-27  16:50:03 一.什么是TypeScript? TypeScript是javasc ...

  3. 感受typescript定义变量和数据类型的神奇魔力

    变量和数据类型 你的Javascript能力到达瓶颈?那是因为你还不会typescript.掌握TS,让你的开发更加准确简洁. 今天的学习中,我们接着从TS的数据类型和变量入手,感受它们的奇妙魔力. ...

  4. ClickHouse(02)ClickHouse架构设计介绍概述与ClickHouse数据分片设计

    ClickHouse核心架构设计是怎么样的?ClickHouse核心架构模块分为两个部分:ClickHouse执行过程架构和ClickHouse数据存储架构,下面分别详细介绍. ClickHouse执 ...

  5. Redis常用数据类型介绍、使用场景及其操作命令

    Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...

  6. Hadoop数据类型介绍

    我们知道hadoop是由Java 编程写的.因此我们使用Java开发环境来操作HDFS,编写mapreduce也是很自然的事情.但是这里面hadoop却对Java数据类型进行了包装,那么hadoop的 ...

  7. C 各种数据类型介绍

    1.各种数据类型介绍: 基本数据类型最主要的特点是,其值不可以再分解为其它类型.也就是说,基本数据类型是自我说明的. 1.1整型 整形包括短整型.整形和长整形. 1.1.1短整形 short a=1; ...

  8. 以太坊智能合约 Solidity 的常用数据类型介绍

    目录 目录 1.数组 1.1.对数组的增删改查操作. 2.String.Bytes.Mapping的使用 3.Enums 和 Structs 的简单应用 4.Ether 单位和 Time 单位 5.A ...

  9. MySQL:数据类型介绍

    数据类型介绍 一.整数类型(可以添加自增约束条件) 数据类型 存储需要 有符号 无符号 tinyint 1个字节 -2^7~2^7-1 0~2^8 smallint 2个字节 -2^15~2^15-1 ...

随机推荐

  1. 慕课网金职位 Python工程师 百度网盘下载

    百度网盘链接:https://pan.baidu.com/s/1xshLRO3ru0LAsQQ0pE67Qg 提取码:bh9f 如果失效加我微信:610060008[视频不加密,资料代码齐全,超清一手 ...

  2. OPC UA 统一架构) (二)

    OPC UA (二) 重头戏,捞取数据,才是该干的事.想获取数据,先有数据源DataPrivade,DataPrivade的数据集合不能和BaseDataVariableState的集合存储同一地址, ...

  3. REST以及RESTful

    java作为一门后端语言,其厉害之处在于web,大家比较熟知的各种网络应用,java都能做,那么在这个移动优先的时代,如何继续发挥java的强大呢.通常是让java作为一个app的服务端,为app客户 ...

  4. HMS Core华为分析丨受众细分,多场景促进精益运营

    用户的偏好不同,对产品的需求也不一样,要想更好地培养用户粘性,就需要因人施策,精细化运营,而受众细分是精细化运营的重要方法之一.受众细分是根据用户属性和行为数据,将具有相同或类似特征的用户归为一个群组 ...

  5. Git轻松入门1:本地仓库篇

    什么是Git 版本控制系统 首先我们要明白,什么是版本控制系统(version control systems)? 版本控制系统,顾名思义,就是能控制文件处于哪个版本的系统. e.g. 你在博客园里编 ...

  6. Mysql数据库用户及用户权限管理,Navicat设置用户权限

    Mysql数据库用户及用户权限管理,Navicat设置用户权限 一.Mysql数据库的权限 1.1 mysql数据库用户权限级别 1.2 mysql数据库用户权限 1.3 存放用户权限表的说明 二.用 ...

  7. JavaWeb——Cookie,Session学习汇总

    什么是Cookie Cookie的作用 安全性能 Cookie的语法 Cookie注意细节 Cookie实例练习 什么是会话Session Session语法 Session与浏览器窗口的关系 ses ...

  8. Neeto-Vue:我为了记笔记,手写了一个为知笔记客户端

    构建自托管的笔记系统 这两年各种笔记系统快速井喷,好像谁都能来掺一脚,app store随便搜索一个关键字就会有一大堆的结果,从老牌的印象笔记,Bear,MWeb,有道云笔记再到新星专注笔记之类,从买 ...

  9. 【疯狂挖坑】linux服务器尝试中的问题(nohup等)

    实验环境:Ubuntu 16.0.4 首当其冲: 1. nohup使用及究极重要事项 我们用服务器肯定都是想在服务器存点什么.让服务器帮我们干点什么,这时候就需要nohup(no hang up)提供 ...

  10. EF6.2加载速度慢的解决方案

    最近的项目中一直有反馈,EF在第一次启动之后调用的话,加载速度很慢,在网上搜索了一下,基本就是三种解决方案. 在程序启动的时候将映射视图缓存下来. 使用Ngen生成EF的本地镜像. IIS8内置功能 ...