Typescript之数据类型

文章目录

    • 布尔类型(boolean)
    • 数字类型(number)
    • 字符串类型(string)
    • 数组类型(array)
    • 元组类型(tuple)
      • 越界的元素
    • 枚举类型(enum)
      • 普通枚举
      • 常数枚举
    • 任意类型(any)
      • 任意值的属性和方法
      • 未声明类型的变量
      • 补充
    • null 和 undefined
    • void 类型
    • never类型
      • 3种方式返回值类型为never
      • strictNullChecks
      • never 和 void 的区别
      • Symbol
      • BigInt
    • 包装对象(Wrapper Object)
      • 示例一
      • 示例二


布尔类型(boolean)

let married: boolean=false;

注意,使用构造函数 Boolean 创造的对象不是布尔值:

let createdByNewBoolean: boolean = new Boolean(1);

// Type 'Boolean' is not assignable to type 'boolean'.
//   'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.

事实上 new Boolean() 返回的是一个 Boolean 对象:

let createdByNewBoolean: Boolean = new Boolean(1);

直接调用 Boolean 也可以返回一个 boolean 类型:

let createdByBoolean: boolean = Boolean(1);

在 TypeScript 中,boolean 是 JavaScript 中的基本类型,而 Boolean 是 JavaScript 中的构造函数。其他基本类型(除了 nullundefined)一样,不再赘述。

数字类型(number)

使用 number 定义数值类型:

let decLiteral: number = 6;

// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;

// ES6 中的八进制表示法
let octalLiteral: number = 0o744;

// ES6 中的十六进制表示法
let hexLiteral: number = 0xf00d;

let notANumber: number = NaN;
let infinityNumber: number = Infinity;

编译结果:

var decLiteral = 6;

// ES6 中的二进制表示法
var binaryLiteral = 10;

// ES6 中的八进制表示法
var octalLiteral = 484;

// ES6 中的十六进制表示法
var hexLiteral = 0xf00d;

var notANumber = NaN;
var infinityNumber = Infinity;

其中 0b10100o744 是 ES6 中的二进制和八进制表示法,它们会被编译为十进制数字。

字符串类型(string)

使用 string 定义字符串类型:

let myName: string = 'Tom';
let myAge: number = 25;

// 模板字符串
let sentence: string = `Hello, my name is ${myName}.
I'll be ${myAge + 1} years old next month.`;

编译结果:

var myName = 'Tom';
var myAge = 25;
// 模板字符串
var sentence = "Hello, my name is " + myName + ".\nI'll be " + (myAge + 1) + " years old next month.";

数组类型(array)

TypeScript像JavaScript一样可以操作数组元素。 有两种方式可以定义数组。 第一种,可以在元素类型后面接上 [],表示由此类型元素组成的一个数组:

let list: number[] = [1, 2, 3];

第二种方式是使用数组泛型,Array<元素类型>:

let list: Array<number> = [1, 2, 3];

元组类型(tuple)

  • 在 TypeScript 的基础类型中,元组( Tuple )表示一个已知数量类型的数组
let zhufeng: [string, number] = ['zhufeng', 5];
console.log(zhufeng[0].length)  // 输出:7
console.log(zhufeng[1].toFixed(2));   // 输出:5.00
元组 数组
每一项可以是不同的类型 每一项都是同一种类型
有预定义的长度 没有长度限制
用于表示一个固定的结构 用于表示一个列表
const animal: [string, number, boolean] = ['zhufeng', 10, true];

  • 固定长度的数组
  • 数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
  • 元组起源于函数编程语言(如 F#),这些语言中会频繁使用元组。

越界的元素

当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:

let tom: [string, number];
tom = ['Tom', 25];
tom.push('male');
tom.push(true);

// Argument of type 'true' is not assignable to parameter of type 'string | number'.

枚举类型(enum)

  • 事先考虑某一个变量的所有的可能的值,尽量用自然语言中的单词表示它的每一个值
  • 比如性别、月份、星期、颜色、单位、学历

普通枚举

enum Gender {
    GIRL,
    BOY
}
console.log(`李雷是${Gender.BOY}`);  // 输出: 李雷是1
console.log(`韩梅梅是${Gender.GIRL}`);  // 输出: 韩梅梅是0

enum Week {
    MONDAY = 10,
    TUESDAY = 20
}
console.log(`今天是星期${Week.MONDAY}`);  // 输出:今天是星期10 
enum Color {Red, Green, Blue}
let c: Color = Color.Green;

默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1开始编号:

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

或者,全部都采用手动赋值:

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];

console.log(colorName);  // 显示'Green'因为上面代码里它的值是2

常数枚举

  • 常数枚举与普通枚举的区别是,它会在编译阶段被删除,并且不能包含计算成员。
  • 假如包含了计算成员,则会在编译阶段报错
const enum Colors {
    Red,
    Yellow,
    Blue
}

let myColors = [Colors.Red, Colors.Yellow, Colors.Blue];
console.log(myColors) // 输出: [ 0, 1, 2 ]
// 下面这行代码会报错,因为包含了计算成员
const enum Color { Red, Yellow, Blue = "blue".length };
  • enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。

任意类型(any)

  • any就是可以赋值给任意类型
  • 第三方库没有提供类型文件时可以使用any
  • 类型转换遇到困难时
  • 数据结构太复杂难以定义

任意值(Any)用来表示允许赋值为任意类型。

任意值的属性和方法

在任意值上访问任何属性都是允许的:

let anyThing: any = 'hello';
console.log(anyThing.myName);
console.log(anyThing.myName.firstName);

也允许调用任何方法:

let anyThing: any = 'Tom';
anyThing.setName('Jerry');
anyThing.setName('Jerry').sayHello();
anyThing.myName.setFirstName('Cat');

可以认为,声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值

未声明类型的变量

变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型

let something;
something = 'seven';
something = 7;

something.setName('Tom');

等价于

let something: any;
something = 'seven';
something = 7;

something.setName('Tom');

补充

// 任意类型 any,如果定义为any类型,那么就跟js差不多了,就不会进行类型检查
let root: any = document.getElementById('root')
root.style.color = "red"

// HTMLElement类型,补充: | 是或的意思
let element: (HTMLElement | null) = document.getElementById('root')
// 加了! 叫 非空断言  就是告诉ts 放心 我肯定不会是null
element!.style.color = 'green'

null 和 undefined

void 的区别是,undefinednull 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量,但是注意,你必须要设置【“strictNullChecks”: false】才可以生效,,strictNullChecks意思是严格空检查,设置为true后,null 和 undefined 就不是其他类型的子类型了,那么就不可以赋值给其他类型了,undefined就只能赋值给undefined类型和any类型,null也是如此

// 注意,你必须要设置【"strictNullChecks": false】才不会报错
let x: number;
x = 1;
x = undefined;    
x = null;  
let y: number | null | undefined;
y = 1;
y = undefined;   
y = null;   
let u: undefined = undefined;
let n: null = null;
// 这样不会报错
let num: number = undefined;
// 这样也不会报错
let u: undefined;
let num: number = u;

void 类型的变量不能赋值给 number 类型的变量:

let u: void;
let num: number = u;

// Type 'void' is not assignable to type 'number'.

void 类型

  • void 表示没有任何类型
  • 当一个函数没有返回值时,TS 会认为它的返回值是 void 类型。
function greeting(name: string): void {
    console.log('hello', name);
    //当我们声明一个变量类型是 void 的时候,它的非严格模式(strictNullChecks:false)下仅可以被赋值为 null 和 undefined
    
    //严格模式(strictNullChecks:true)下只能返回undefined

    return null;
    return undefined;
}

greeting('zsy')

function greeting(): void {
    return null;  // 当设置【strictNullChecks的值为false】,不会报错,说明null在此种情况可以赋值给void,反之就不行了,但是undefined好像两种情况都可以赋值给null
}

声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefinednull(只在 --strictNullChecks 未指定时):

let unusable: void = undefined;

never类型

  • never是其它类型(null undefined)的子类型,代表不会出现的值
  • never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型
  • never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。

3种方式返回值类型为never

一般运用在函数抛出异常,函数死循环,或函数没有返回值

    1. 抛出异常
// 返回never的函数 必须存在 无法达到( unreachable ) 的终点
function error(message: string): never {
    throw new Error(message);
    console.log('ok')  // 出现异常,终止了
}

// 由类型推论可以知道result1的类型为 never
let result1 = error('hello');
    1. 死循环

// 返回never的函数 必须存在 无法达到( unreachable ) 的终点
function infiniteLoop(): never {
    while (true) { }
}
// 由类型推论可以知道result3的类型为 never
let result3 = infiniteLoop()
    1. 推断的返回值为never
// 返回never的函数 必须存在 无法达到( unreachable ) 的终点
function error(message: string): never {
    throw new Error(message);
}

// 由类型推论可以知道result1的类型为 never
let result1 = error('hello');


function fail() {
    return error("Something failed");
}
// 由类型推论可以知道result2的类型为 never
let result2 = fail();

function fn(x: number | string) {
    if (typeof x === 'number') {
        console.log(x)
    } else if (typeof x === 'string') {
        console.log(x)
    } else {
        console.log(x)  // 这里的x是never类型,因为x参数只能是number或者string,不可能走到这里
    }
}

strictNullChecks

never 和 void 的区别

  • void 可以被赋值为 null 和 undefined的类型。 never 则是一个不包含值的类型。
  • 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。

Symbol

  • 我们在使用 Symbol 的时候,必须添加 es6 的编译辅助库
  • Symbol 是在ES2015之后成为新的原始类型,它通过 Symbol 构造函数创建
  • Symbol 的值是唯一不变的
const sym1 = Symbol('key');
const sym2 = Symbol('key');
console.log(Symbol('key') === Symbol('key')) // false

BigInt

  • 使用 BigInt 可以安全地存储和操作大整数
  • 我们在使用 BigInt 的时候,必须添加 ESNext 的编译辅助库
  • 要使用1n需要 “target”: “ESNext”
  • number和 BigInt类型不一样,不兼容
const max = Number.MAX_SAFE_INTEGER;// 2^53-1
console.log(max + 1 === max + 2);  // true

// 注意: 在ts配置文件加入 "lib": ["ESNext"] ,写了ESNext就能支持 es6的 Symbol,BigInt,ESNext表示最新JS版本的意思

// 在ts配置文件加入 "lib": ["dom"] ,就支持console.log() 这样的打印输出了

const max = BigInt(Number.MAX_SAFE_INTEGER);
console.log(max + 1n === max + 2n);  // false
// 下面都会报错,因为 number和bigint两种类型的值不能互相赋值
let foo: number;
let bar: bigint;
foo = bar;
bar = foo;

包装对象(Wrapper Object)

  • JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。
  • 所有的原始数据类型都没有属性(property)
  • 原始数据类型
    • 布尔值
    • 数值
    • 字符串
    • null
    • undefined
    • Symbol
let tmp = 'zhufeng';
console.log(tmp.toUpperCase()); // 'ZHUFENG'

console.log((new String('zhufeng')).toUpperCase());  // 'ZHUFENG'
// let isOK: boolean = true; // 编译通过

// let isOK: boolean = Boolean(1) // 编译通过

let isOK: boolean = new Boolean(1); // 编译失败   期望的 isOK 是一个原始数据类型
  • object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。

示例一

let name2 = 'zsy'
console.log(name2.toUpperCase())  // 相当于写了下面一行代码,也就是js内部会自动包装成对象类型,也就是说当你在调用基本类型的方法的时候,内部都会自动帮我们包装成对象类型
console.log(new String(name2).toUpperCase())

示例二

let isOk:boolean = true
// Boolean(1) 返回的是基本类型
let isOk:boolean = Boolean(1)
// new Boolean(1) 返回的是对象类型,不能赋值给基本类型,因此报错
let isOk:boolean = new Boolean(1) // 会报错

你可能感兴趣的:(typescript,javascript,前端)