Skip to content

TS 数据类型

ts 数据类型表

TS 类型大致分为以下几类 基本类型:string、number、boolean、symbol、bigint、null、undefined 引用类型:array、 Tuple(元组)、 object(包含Object和{})、function 特殊类型:any、unknow、void、never、Enum(枚举) 其他类型:类型推理、字面量类型、交叉类型

ts 类型表

数据类型关键字描述
任意类型any声明为 any 的变量可以赋予任意类型的值。
数字类型number双精度 64 位浮点值。它可以用来表示整数和分数。
let binaryLiteral: number = 0b1010; // 二进制
let octalLiteral: number = 0o744; // 八进制
let decLiteral: number = 6; // 十进制
let hexLiteral: number = 0xf00d; // 十六进制
大整数bigint提供了一种方式来表示所有大于 2^53 的数字
let bigNum: bigint = 10n;
字符串类型string一个字符系列,使用单引号(')或双引号(")来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式。
let name: string = "Runoob";
let years: number = 5;
let words: string = `您好,今年是 ${ name } 发布 ${ years + 1} 周年`;
布尔类型boolean表示逻辑值:true 和 false。
let flag: boolean = true;
数组类型声明变量为数组。

// 在元素类型后面加上[]
let arr: number[] = [1, 2];
// 或者使用数组泛型
let arr: Array<number> = [1, 2];
元组元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
let x: [string, number];
x = ['Runoob', 1]; // 运行正常
x = [1, 'Runoob']; // 报错
console.log(x[0]); // 输出 Runoob
对象声明变量为对象
枚举enum枚举类型用于定义数值集合。
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c); // 输出 2
voidvoid用于标识方法返回值的类型,表示该方法没有返回值。
function hello():void {
alert("Hello Runoob");
}
symbolsymbol表示一个独一无二的值
nullnull表示对象值缺失。
undefinedundefined用于初始化变量为一个未定义的值
nevernevernever 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

基本数据类型

基本类型:string、number、boolean、symbol、bigint、null、undefined

ts
// 字符串
let str: string = "Domesy"

// 数字
let num: number = 7

// 布尔
let bool: boolean = true

// symbol
let sym: symbol = Symbol();
  
// bigint
let big: bigint = 10n
    
// null
let nu: null = null

// undefined
let un: undefined = undefined

需要注意

  • null 和 undefined 两个类型一旦赋值上,就不能在赋值给任何其他类型
  • symbol是独一无二的,假设再定义一个 sym1,那么sym === sym1 为 false

引用数据类型

引用类型:array、 Tuple(元组)、 object(包含Object和{})、function

Array(数组)

数组对象是使用单独的变量名来存储一系列的值。 两种书写方式:

  • 类型名称 + []
  • Array<数据类型

示例

ts
let arr1: number[] = [1, 2, 3]
    
let arr2: Array<number> = [1, 2, 3]

let arr2: Array<number> = [1, 2, '3'] // error

//要想是数字类型或字符串类型,需要使用 |
let arr3: Array<number | string> = [1, 2, '3'] //ok

Tuple(元组)

Tuple 和数组很像,可以说是 Array 的一种特殊情况,针对上面的 arr3,我们看他的类型可以是string也可以是number,但对每个元素没有作出具体的限制。

那么 Tuple 的作用就是限制元素的类型并且限制个数的数组,同时 Tuple这个概念值存在于TS,在JS上是不存在的

这里存在一个问题:在TS中,是允许对 Tuple 扩增的(也就是允许使用 push方法),但在访问上不允许

ts
// 中括号的形式 可以对数组中的每个元素进行限制 这种形式就是 Tuple(元组)
let t: [number, string] = [1, '2'] // ok  

// 元素2 应为字符串 却赋值了一个 数字  因此 会得到 error
let t1: [number, string] = [1, 3] // error
// 元素 个数不对 因此 会得到 error
let t2: [number, string] = [1] // error
// 同上
let t3: [number, string] = [1, '1', true] // error

let t5: [number, string] = [1, '2'] // ok

t.push(2) // 可以push 
console.log(t) // [1, '2', 2] 能够输出结果

let a =  t[0] // ok
let b = t[1] // ok
let c = t[2] // error  通过索引无法得到结果

Object(对象)

  • object 非原始类型,在定义上直接使用 object 是可以的,但你要更改对象的属性就会报错,原因是并没有使对象的内部具体的属性做限制,所以需要使用 {} 来定义内部类型
ts
// 这种形式 不能更改属性值
let obj1: object = { a: 1, b: 2}
obj1.a = 3 // error

// 可以修改对象中的值 因为做了类型限时
let obj2: { a: number, b: number } = {a: 1, b: 2}
obj2.a = 3 // ok
  • Object(大写的O),代表所有的原始类型或非原始类型都可以进行赋值,除了null和`undefined
ts
let obj: Object;
obj = 1 // ok
obj = '1'// ok
obj = true// ok
obj = []// ok
obj = {}// ok
obj = null// ok
obj = undefined//error

let obj1:object;
obj1 = 1 // error
obj1 = '1' // error
...
obj1 = {} // ok

Function(函数)

  • 有两种方式,一种为 function, 另一种为箭头函数
  • 在书写的时候,也可以写入返回值的类型,如果写入,则必须要有对应类型的返回值,但通常情况下是省略,因为TS的类型推断功能够正确推断出返回值类型
ts
// 未指定返回值类型
function setName1() { //ok
  console.log("hello");
}
setName1("Domesy"); // "hello"

// 指定返回值类型需为 string
function setName2():string { //error
  console.log("hello");
}
setName2("Domesy");

// 指定返回值类型为string 返回数字类型 会得到error
function setName3():string { //error
  console.log("hello");
  return 1
}
setName3("Domesy");

// 指定返回值类型为string 返回字符串类型 得到ok
function setName4(): string { //ok
  console.log("hello");
  return "name"
}
setName4("Domesy"); // "hello"

//箭头函数与上述同理
const setName5 = () => console.log("hello",);
setName5("Domesy") // "hello",  "Domesy"

参数类型

  • 可选参数: 如果函数要配置可有可无的参数时,可以通过 ? 实现,切可选参数一定要在最后面
  • 默认参数:函数内可以自己设定其默认参数,用 = 实现
  • 剩余参数:仍可以使用扩展运算符 ...
ts
// 可选参数
const setInfo1 = (name: string, age?: number) => console.log(name, age)
setInfo1('Domesy') //"Domesy",  undefined
setInfo1('Domesy', 7) //"Domesy",  7

// 默认参数
const setInfo2 = (name: string, age: number = 11) => console.log(name, age)
setInfo2('Domesy') //"Domesy",  11
setInfo2('Domesy', 7) //"Domesy",  7

// 剩余参数
const allCount = (...numbers: number[]) => console.log(`数字总和为:${numbers.reduce((val, item) => (val += item), 0)}`)
allCount(1, 2, 3) //"数字总和为:6"

函数重载

函数重载: 是使用相同名称和不同参数数量或类型创建多个方法的一种能力。 在 TypeScript 中,表现为给同一个函数提供多个函数类型定义。 简单的说:可以在同一个函数下定义多种类型值,最后汇总到一块。

在 TypeScript中只是提供了函数重载的写法及类型验证,具体的函数实现逻辑及判断还需自己实现。TS并不会自动将你的多个重名函数进行合并。

函数重载的几点定义:

  1. 函数的名称必须相同
  2. 函数的参数必须不同
  3. 通过参数区分函数,说明多个函数肯定不会是一个地址空间
  4. 在一个作用域范围

函数重载的意义: 在于能够让你知道传入不同的参数,得到不同的结果。

注意事项:

  • 重载是方法名字必须相同,而参数必须不同,返回类型可以相同也可以不同。
  • 每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
  • 必须吧函数的精确定义放在最前面

参数类型不同:

ts
function disp(a:string):void; 
function disp(b:number):void;

参数数量不同:

ts
function disp(n1:number):void; 
function disp(x:number,y:number):void;

参数类型顺序不同:

ts
function disp(n1:number,s1:string):void; 
function disp(s:string,n:number):void;
  • 如果参数类型不同,则参数类型可以设置为 any。
  • 参数数量不同你可以将不同的参数设置为可选。

示例:

ts
function disp(s1:string):void; 
function disp(n1:number,s1:string):void; 
 
// function disp(x:any,y?:any):void { 
function disp(x:string|number,y?:string):void { 
    console.log(x); 
    console.log(y); 
} 
disp("abc") // ok
disp(1,"xyz"); // ok
disp(1); // error

特殊类型

any

在 TS 中,任何类型都可以归于 any 类型,所以any类型也就成了所有类型的顶级类型,同时,如果不指定变量的类型,则默认为any类型, 当然不推荐使用该类型,因为这样丧失了TS的作用

ts
let a:any; //等价于 let d 
a = '1';
a = 2;
a = true;
a = [1, 2, 3];
a = {}

unknow

与any一样,都可以作为所有类型的顶级类型,但 unknow更加严格,那么可以说除了any 之下的第二大类型。接下来对比下any,主要严格于一下两点:

  • unknow会对值进行检测,而类型any不会做检测操作,说白了,any类型可以赋值给任何类型,但unknow只能赋值给unknow类型和any类型
  • unknow不允许定义的值有任何操作(如 方法,new等),但any可以
ts
let u:unknown;
let a: any;

u = '1'; //ok
u = 2; //ok
u = true; //ok
u = [1, 2, 3]; //ok
u = {}; //ok

let value:any = u //ok
let value1:any = a //ok
let value2:unknown = u //ok
let value3:unknown = a //ok
let value4:string = u //error
let value5:string = a //ok
let value6:number = u //error
let value7:number = a //ok
let value8:boolean = u //error
let value9:boolean = a //ok

u.set() // error
a.set() // ok
u() // error
a() //ok
new u() // error
new a() //ok

void

用于标识方法返回值的类型,表示该方法没有返回值

当一个函数,没有返回值时,TS会默认他的返回值为 void 类型

ts
function hello(): void {
    alert("Hello");
    // return // ok
    // return undefined // ok
    // return '1' //error
    return 1 //error
}

never

never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

在函数中表示一个函数永远不存在返回值,TS会认为类型为 never,那么与 void 相比, never应该是 void子集, 因为 void实际上的返回值为 undefined,而 never 连 undefined也不行

符合never的情况有:当抛出异常的情况和无限死循环

ts
let str:never
str = 1 // error
str = '1' // error
str = undefined // error
str = null // error
str = ''// error
str = true// error
str = []// error‘

function error(err): never {
  // 主动抛出错误
  throw new Error(err)
}

function error1(): never {
  while (true) {}
}

Enum(枚举)

可以定义一些带名字的常量,这样可以清晰表达意图或创建一组有区别的用例

注意:

  • 枚举的类型只能是 string 或 number
  • 定义的名称不能为关键字

同时我们可以看看翻译为ES5是何样子

数字枚举

  • 枚组的类型默认为数字类型,默认从0开始以此累加,如果有设置默认值,则只会对下面的值产生影响
  • 同时支持反向映射(及从成员值到成员名的映射),但智能映射无默认值的情况,并且只能是默认值的前面

示例

ts
enum list {
  A,
  B = 7,
  C,
  D
}
console.log(list.A) // 0 正向映射
console.log(list[0]) // A 反向映射
console.log(list[1]) // undefined 反向映射
console.log(list[8]) // C

编译后:

js
var list;
(function (list) {
    list[list["A"] = 0] = "A";
    list[list["B"] = 7] = "B";
    list[list["C"] = 8] = "C";
    list[list["D"] = 9] = "D";
})(list || (list = {}));
console.log(list.A); // 0 正向映射
console.log(list[0]); // A 反向映射
console.log(list[1]); // undefined 反向映射
console.log(list[8]); // C

字符串枚举

字符串枚举要注意的是必须要有默认值,不支持反向映射

示例

ts
enum list { // ok
  A = 'AA',
  B = 'BB',
  C = "CC",
}

enum list1 { // error
  A = 'AA',
  B = 'BB',
  C = "CC",
  D
}
console.log(list.A);
console.log(list1.A);

编译后

js
var list;
(function (list) {
    list["A"] = "AA";
    list["B"] = "BB";
    list["C"] = "CC";
})(list || (list = {}));
var list1;
(function (list1) {
    list1["A"] = "AA";
    list1["B"] = "BB";
    list1["C"] = "CC";
    list1[list1["D"] = void 0] = "D";
})(list1 || (list1 = {}));
console.log(list.A);
console.log(list1.A);

常量枚举

除了数字类型和字符串类型之外,还有一种特殊的类型,那就是常量枚举,也就是通过const去定义enum,但这种类型不会编译成任何 JS,只会编译对应的值

示例

ts
const enum list { // ok
  A = 'AA',
  B = 'BB',
  C = "CC",
} // 将不会被编译

console.log(list.A);
console.log(list.B);

编译后

js
console.log("AA" /* A */);
console.log("BB" /* B */);

异构枚举

包含了 数字类型 和 字符串类型 的混合,反向映射一样的道理

示例

ts
enum list { // ok
  A,
  B,
  C = 'CC',
  D = 7
} // 将不会被编译

console.log(list.A) // 0
console.log(list.B) // 1
console.log(list.C) // cc
console.log(list.D) // 7
console.log(list[7]) // D

编译后

js
var list;
(function (list) {
    list[list["A"] = 0] = "A";
    list[list["B"] = 1] = "B";
    list["C"] = "CC";
    list[list["D"] = 7] = "D";
})(list || (list = {})); // 将不会被编译
console.log(list.A); // 0
console.log(list.B); // 1
console.log(list.C); // cc
console.log(list.D); // 7
console.log(list[7]); // D

类型推断

  • 当类型没有给出时,TypeScript 编译器利用类型推断来推断类型。

  • 如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型。

示例

ts
var num = 2;    // 类型推断为 number
var str = '2';    // 类型推断为 number
console.log("num 变量的值为 "+num); 
num = "12";    // error
str = 2 // error
console.log(num);

编译后

js
var num = 2; // 类型推断为 number
var str = '2'; // 类型推断为 number
console.log("num 变量的值为 " + num);
num = "12"; // error
str = 2; // error
console.log(num);

字面量类型

字面量类型:在TS中,我们可以指定参数的类型是什么,目前支持字符串、数字、布尔三种类型。字面量类型就是通过字面量的形式指定数据类型。如果使用字面量类型则数据的值只能为字面量的值

示例

ts
var str: 'string' = 'string'
str = 'str' //error

var num: 1 | 2 = 1
num = 2 // ok
num = 3 // error

var bool: true | false = true
bool = false // ok
bool = 1 // error

编译后

js
var str = 'string';
str = 'str'; //error
var num = 1;
num = 2; // ok
num = 3; // error
var bool = true;
bool = false; // ok
bool = 1; // error

交叉类型

交叉类型: 将多个类型合并为一个类型,使用&符号连接。

示例

ts
var str: string & number //never

var bool: Boolean & number//never

// type 用来定义一个类型 别名
type MyType = { a: string }
type MyType1 = { b: number }

type MyType2 = MyType & MyType1
let obj: MyType & MyType1 = { a: '123', b: 456 } // ok
let obj1: MyType2 = { a: '123', b: 456 } // ok

编译后

js
var str;//never
var bool;//never
var obj = { a: '123', b: 456 }; // ok
var obj1 = { a: '123', b: 456 }; // ok

Released under the MIT License.