typescript类型基础

typescript类型基础

枚举类型

enum Season {
    Spring,
    Summer,
    Fall,
    Winter
}

数值型枚举

enum Direction {
    Up,
    Down,
    Left,
    Right
}
const direction:Direction = Direction.up

每个数值型枚举成员都表示一个具体的数字,如果在定义一个枚举的时候没有设置枚举成员的值,Typescript会自动计算每个枚举成员的值。第一个枚举成员的值为0,后续++

enum Direction {
    Up = 1, // 1
    Down, // 2
    Left = 10, // 10
    Right // 11
}

数值型枚举是number类型的子类型,允许将数值型枚举赋值给number类型。

const direction: number = Direction.up

Number类型也能够赋值给枚举类型,即使number类型的值不在枚举成员值的列表中也不会产生错误

enum Direction {
    Up,
    Down,
    Left,
    Right
}
const d1: Direction = 0
const d2: Direction = 10 // 不会产生错误

字符串枚举

字符串枚举成员必须使用字符串字面量或者另一个字符串枚举成隐患来初始化。

enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT'
    U = Up,
    D = Down
    L = Left
    R = Right
}

字符串枚举是string类型的子类型,因此允许将字符串枚举类型赋值给string类型。下例中常量direction为string类型

enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT'
}
const direction: string = Direction.Up

不允许将string类型赋值给字符串枚举类型

enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT'
}
const direction: Direction = 'UP' // 编译错误,不能将类型up赋值给direction

异构型枚举

异构型枚举: TypeScript允许在一个枚举中同时定义数值类型枚举成员和字符串枚举成员。

enum Color {
    Black = 0,
    White = 'White'
}

不允许使用计算的值作为枚举成员的初始值

enum Color {
    Black = 0 + 0 // 不允许使用计算的值作为枚举成员的初始值
}

在异构型枚举中,必须为在字符串枚举成员之后的数值型枚举成员指定一个初始值。

enum ColorA {
    Black,
    White = 'white'
}
enum ColorB {
    White = 'white'
    Black // 枚举成员必须有一个初始值
}

枚举成员映射

任何类型的枚举,都可以通过枚举成员名来访问枚举成员。

enum Bool {
    False = 0,
    True = 1
}
Bool.False ;
Bool.True
Bool[Bool.False] // 'False'
Bool[Bool.True] // 'True'

常量枚举成员和计算枚举成员

常量枚举成员

若枚举类型的第一个枚举成员没有定义初始值。枚举成员是常量枚举成员并且初始值为0
若枚举成员没有定义初始值并且和他相邻的成员是常量枚举成员并且初始值为紧邻的前一个枚举成员值加一,如果紧邻的前一个枚举成员的值不是数值型常量,就会产生错误

enum Foo {
    A,
    B
}
enum Bar {
    c = 'c',
    d // 编译错误
}
  1. 常量枚举表达式可以是数字字面量,字符串字面量和不包含替换值的模板字面量
  2. 常量枚举表达式可以是对前面定义的常量枚举成员的引用
  3. 常量枚举表达式可以是分组运算符包围起来的常量枚举表达式
  4. 常量枚举表达式中可以使用一元运算符,操作数必须为常量枚举表达式
  5. 常量枚举表达式可以使用二元运算符,两个操作数必须是常量枚举表达式
enum Foo {
    A = 0,
    B = `B`, // 无替换的模板字面量
    C = 'C'  // 字符串字面量
    D = A // 引用前面定义的常量枚举成员
}
enum Bar {
    A = -1 // 一元运算符
    B = 1 + 2// 二元运算符
    C = (4 / 2) * 3 // 分组运算符
}
字面量枚举成员[常量枚举成员的子集]
  1. 枚举成员没有定义初始值
  2. 枚举成员的初始值为数字字面量、字符串字面量和不包含替换值
    的模板字面量
  3. 枚举成员的初始值为对其他字面量枚举成员的引用。
    在这里插入图片描述
联合枚举类型

当枚举类型中的所有成员都是字面量枚举成员的时候,枚举类型为联合枚举类型

联合枚举成员类型

联合枚举类型中的枚举成员除了能够表示一个常量值外,还能表示一种类型,即联合枚举成员类型

enum Direction {
    Up,
    Down,
    Left,
    Right
}
const up: Direction.Up = Direction.Up

联合枚举成员类型是联合枚举类型的子类型,因此可以将联合枚举类型成员赋值给联合枚举类型

enum Direcition {
    Up,
    Down,
    Left,
    Right
}
const up: Direction.Up = Direction.Up
const direction: Direction = up
联合枚举类型

联合枚举类型是所有联合枚举成员构成的联合类型

enum Direction {
    Up,
    Down,
    Left,
    Right
}
type UnionDirectionType = 
                    | Direction.Up
                    | Direction.Down
                    | Direction.Left
                    | Direction.Right

Direction枚举是联合枚举类型,等同于联合类型UnionDirectionType,其中|符号是定义联合类型的语法。由于联合枚举类型是由固定数量的联合枚举成员类型构成的联合类型
联合枚举类型是由固定数量的联合枚举成员类型构成的联合类型,编辑器可以通过该性质对代码进行检查。

const枚举类型

枚举类型是typescript对JavaScript的拓展

enum Direction {
    Up,
    Down,
    Left,
    Right
}
const d: Direction = Direction.Up
// javascript 这种情况下有枚举成员值映射到枚举成员名的反向映射
"use strict"
var Direction
(funciton (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
    Direction[Direction["Left"] = 2] = "Left";
    Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}))
const d = Direction.Up
// JavaScript没有映射的情况
"use strict"
var Direction
(function (Direction) {
    Direction["Up"] = 0
    Direction["Down"] = 1
    Direction["Left"] = 2
    Direction["Right"] = 3
})(Direction || (Direction = {}))

完全不需要生成Direction对象相关的代码,只需要将"Direction.Up"替换成为它表示的常量0就可以。

"use strict"
const d = 0

const 枚举类型具有相同的效果,const枚举类型将在编译阶段被完全删除,并且使用了const枚举类型的地方会直接将const枚举成员的值内联到代码中

const enum Direction {
    Up,
    Down,
    Left,
    Right
}
const directions = {
    Directions.Up,
    Directions.Down,
    Directions.Left,
    Directions.Right
}

代码经过typescript编译器编译后生成的JavaScript代码如下

"use strict"
const diretions = [
    0  /*Up */,
    1  /*Down */,
    2  /*Left */,
    3  /*Right */
]

为了便于代码调试和保持代码的可读性,typescript编辑器内链了注释,注释为枚举成员的名字

字面量类型

Typescript支持将字面量作为类型使用,称为字面量类型。

boolean字面量类型

true or false

string字面量类型

字符串字面量和模板字面量都能创建字符串,字符串字面量和不带参数的模板字面量都可以作为string字面量的类型使用

const a : 'hello'  = 'hello'
const b : `world` = `world`

string字面量类型是string类型的子类型,可以将string字面量类型赋值给string类型

const a: 'hello' = 'hello'
const b: `world` = `world`
let c: string
c = a
c = b

数字字面量类型

数字字面量类型包括number字面量类型和bigint字面量类型

const a0: 0b1 = 1;
const b0: 0o1 = 1;
const c0: 1 = 1;
const d0: 0x1 = 1;
const a1: 0b1n = 1n;
const b1: 0o1n = 1n;
const c1: 1n = 1n;
const d1: 0x1n = 1n;

除了正数外,负数也可以作为数字字面量类型

const a0: -10 = -10;
const b0: 10 = 10;
const a1: -10n = -10n;
const b1: 10n = 10n;

number字面量类型和bigint字面量类型分别是number类型和bigint类型的子类型

const one: 1 = 1;
const num: number = one;
const oneN: 1n = 1n;
const numN: bigint = oneN;

枚举成员字面量类型

联合枚举成员类型使用枚举成员字面量形式表示

enum Direction {
    Up,
    Down,
    Left,
    Right
}
const up:Direction.Up =Direction.Up;
const down:Direction.Down=Direction.Down;
const left:Direction.Left = Direction.Left;
const right:Direction.Right=Direction.Right;

单元类型

单元类型又称为单例类型。指的是仅包含一个可能值的类型,由于这个特殊的类型,编译器在处理单元类型的时候不需要关注单元类型表示的具体值

const a: undefined = undefined
const b: null = null
const c: void = undefined
const d: unique symbol = Symbol()
const e: `hello` = 'hello'
enum Foo {A, B}
const f: Foo.A = Foo.A

顶端类型

顶端类型是一种通用类型,被称为通用超类型,在类型系统中,所有的类型都是顶端类型的子类型。

any

any类型是Typescript支持的顶端类型

let x: any
x = true;
x = 'hi';
x = 323;
x = 999n;
x = Symbol();
x = undefiend;
x = null;
x = {};
x = [];
x = function() {}

需要注意的是,虽然any类型是所有类型的父类型,但是TypeScript允许将any类型赋值给任何其他类型。

let x: any;
let a: boolean = x;
let b: string = x;
let c: number = x;
let d: bigint = x;
let e: symbol = x;
let f: void = x;
let g: undefined = x;
let h: null = x;

在any类型上允许执行任意的操作而不会产生编译错误。

–noImplicitAny

typescript中的类型注释是可以选择的,如果一个值没有明确的类型注解,编译器无法自动推断他的类型,那么这个值为any类型。

在大多数情况下,我们想要避免上述情况的发生。因此,TypeScript提供了一个“–noImplicitAny”编译选项来控制该行为。当启用了该编译选项时,如果发生了隐式的any类型转换,那么会产生编译错误。

{
    "compilerOptions": {
        "noImpliciAny": true
    }
}

unknown

unknown类型使用unknow关键字做标识。let x: unknown
根据顶端类型的性质,任何其他的类型都能够赋值给unknown类型。unknown类型是比any类型更加安全的顶端类型。unknown类型只允许赋值给any类型和unknown类型,不允许赋值给任何其他类型。

let x: unknown;
const a1: any = x;
const b1: unknown = x;
// 错误
const a2: boolean = x;
const b2: string = x;
const c2: number = x;

同时在unknown类型上不允许执行绝大部分的操作。

let x: unknown;
// error
x + 1;
x.foo;
x()

在程序中使用unknown类型,需要将其细化为某些具体的类型,否则产生编译错误

function f1 (message: any) {
    return message.length
}
f1(undefined)
function f2(message: unknown) {
    return message.length // 编译错误,属性length不存在
}

此例子中,函数f1的参数message为any类型,在函数体重直接读取参数message的length属性不会产生编译错误,编译器不会对any类型进行任何类型检查,在f2重,参数的类型定义为unknown类型,这样的话,在函数体重不能直接读取参数message的length属性,否则将产生编译错误。

小结

  1. typescript仅有any和unknown两种顶端类型
  2. typescript中的所有类型都能赋值给any类型和unknown类型,两者没有写入的限制
  3. any类型能够赋值给任何其他的类型,不包含马上要介绍的never类型
  4. unknown类型仅仅能赋值给any类型和unknown类型
  5. 使用unknown类型,需要将其细分为某种具体类型

尾端类型

在类型系统中,尾端类型是所有其他类型的子类型,由于一个值不能同时属于所有类型,一个值不能同时为数字类型和字符串类型,因此尾端类型不包含任何值,尾端类型称为空类型或者0类型

never

typescript只有一个尾端类型:never类型,

function f() {
    throw new Error()
}

根据尾端类型的定义,never类型是所有其他类型的子类型,所以,never类型允许赋值给任何类型,尽管不存在never类型的值

let x: never
let a: boolean = x;
let b: string = x;
let c: number = x;
let d: bigint = x;
let e: symbol = x;
let f: void = x;
let g: undefined = x;
let h: null = x;

没有类型是never类型的子类型,所有其他类型都不能赋值给never类型。

let x: never;
let y: never;
x = y;
// 错误
x = true;
x = 'hi'
x = 3.14

never的应用场景

  1. never类型可以作为函数的返回值类型,表示函数无法返回一个值。如果函数体中没有使用return语句,那么在正常执行完函数代码后会返回一个undefined值。在这种情况下,函数的返回值类型是void类型而不是never类型。只有在函数根本无法返回一个值的时候,函数的返回值类型才是never类型。、
  2. 函数中抛出了异常,这会到种子函数终止执行,从而不会返回任何值,这种情况下,函数的返回值为never类型。
    function throwError():never {
        throw new Error()
        // 函数永远无法执行到末尾,返回类型为'never'
    }
    
  3. 函数的代码不是直接抛出异常而是间接的抛出异常,那么函数的返回值类型也是never类型。
    function throwError:never () {
        throww new Error()
    }
    function fail():never {
        ruturn throwError()
    }
    
    fail函数包含了一条return语句,return语句中表达式的类型为never类型,因此fail函数的返回值类型也为never类型。
  4. 函数体中存在无限循环从而导致函数的执行永远也不会结束。在这种情况下函数的返回值也为never类型
    function infiniteLoop(): never {
        while(true) {
        console.log('endless')    
        }
    }
    // infiniteLoop函数的执行永远也不会结束,这意味着它无法正常返回一个值。因此,该函数的返回值类型为never类型
    
  5. 在条件类型中,使用never类型来完成一些类型运算。

数组类型

数组是十分常用的数据结构,它表示一组有序元素的集合。在TypeScript中,数组值的数据类型为数组类型。

数组类型的定义

简便数组类型表示法

简便数组类型表示法借用了数组字面量的语法,通过在数组元素后添加一对方括号"[]"来定义数组。

TElement []
const digits: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8,  9]

如果数组中的元素的类型为复合类型,则需要在数组元素类型上使用分组运算符。

const red: (string | number)[] = ['f',f,0,0,0,0]
泛型数组类型表示法

泛型数组表示法是另一种表示数组类型的方法

Array<TElement>

该语法中 ,Array表示数组类型,

const digits: Array<number> = [0, 1, 2, 3, 4, 5, 6,  7, 8, 9]
const red: Array<string | number> = ['f',f,0,0,0,0]
比较

简便数组类型表示法和泛型类型表示法在功能上没有任何差别,只是在编码风格上有所差。’
在定义简单数组类型的时候,如果数组元素为单一原始类型或者类型引用,使用简便数组表示法会更加清晰和简洁

let a: string[];
let b: HTMLButtonElement[]

如果数组元素是复杂类型,如果是对象类型和联合类型等,可以选择使用泛型数组类型表示法。

let a: Array<string | number> ;
let b: Array<{x: number; y: number}>

数组元素类型

定义了数组类型之后,当访问数组元素的时候能够获得正确的元素的类型信息

const digits: number[] = [0, 1, 2, 3, 4, 5]
const zero = digits[0]
//虽然没有给常量zero添加类型注解,但是TypeScript编译器能够从数组类型中推断出zero的类型为number类型。
const out: number = digits[100]

当访问数组中不存在的元素,将会返回undefined值。typescript的类型系统无法推断出是否存在数组访问过界的情况

自读数组

只读数组和常规数组的区别在于,只读数组只允许程序读取数组,不允许修改和写入数组元素

ReadonlyArray
const red: ReadonlyArray<number> = [255, 0, 0]
readonly

readonly修饰符不允许与泛型数组类型表示法一起使用

const red: readonly number[] = [255, 0, 0]
Readonly

Readonly是typescript提供的一个内置工具类型,用于定义只读对象类型。将类型参数T的所有属性转换为只读
属性

type Readonly<T> = {
    readonly [P in keyof T]: T[P]
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5款智能写作工具,为大家一键生成原创文案

好的文案是能吸引眼球、传递信息&#xff0c;但对于许多人来说&#xff0c;写出好文案是一项耗时耗力的任务。而随着一些智能写作工具的出现&#xff0c;它为我们带来了很大的便利&#xff0c;无论是写作文案还是写作其它的内容&#xff0c;智能写作工具都能轻松帮助我们完成。…

感谢有你 | FISCO BCOS 2024年度第一季度贡献者榜单

挥别春天&#xff0c;FISCO BCOS开源社区迎来了2024年第一季度的共建成果。FISCO BCOS秉承对区块链技术的信仰&#xff0c;汇聚超过5000家企业机构、10万余名个人成员共建共治共享&#xff0c;持续打造更加活跃更加繁荣的开源联盟链生态圈。 开启夏日&#xff0c;我们见证了社…

从源头把控风险:集团多主体合规管理实战技巧分享

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 集团合规管理中&#xff0c;为了规避内外部利益冲突&#xff0c;需要对员工、供应商、经销商、客户、黑名单企业等多主体及其关联主体之间&#xff0c;进行多维度、多层级的关系挖掘与排查&#xff0c;避免利益…

MybatisPlus学习笔记

具体源码见&#xff1a; https://github.com/cug-lucifer/mp-demo/tree/master 快速入门 入门案例 需求&#xff1a; 新增用户功能根据id查询用户根据id批量查询用户根据id更新用户根据id删除用户 使用MybatisPlus的基本步骤 引入MybatisPlus依赖&#xff0c;代替Mybatis…

【题目】2023年全国职业院校技能大赛 GZ073 网络系统管理赛项赛题第4套B模块

2023年全国职业院校技能大赛 GZ073网络系统管理赛项 赛题第4套 模块B&#xff1a;服务部署 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发等多个赛项技术支持 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加…

HackBar 新手使用教程(入门)

啥是Hackbar&#xff1f; Hackbar是一个Firefox 的插件,它的功能类似于地址栏,但是它里面的数据不受服务器的相应触发的重定向等其它变化的影响。 有网址的载入于访问,联合查询,各种编码,数据加密功能。 这个Hackbar可以帮助你在测试SQL注入,XSS漏洞和网站的安全性,主要是帮助…

单单单单单の刁队列

在数据结构的学习中&#xff0c;队列是一种常用的线性数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff09;的原则。而单调队列是队列的一种变体&#xff0c;它在特定条件下保证了队列中的元素具有某种单调性质&#xff0c;例如单调递增或单调递减。单调队列在处理…

[Collection与数据结构] Map与Set(一):二叉搜索树与Map,Set的使用

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

Baidu Comate智能编码助手

Baidu Comate智能编码助手 &#x1f388;1.Baidu Comate的简介&#x1f388;2.安装Baidu Comate&#x1f388;3.Baidu Comate实现功能&#x1f388;4.使用注释进行智能代码提示&#x1f388;5.结束语 &#x1f388;1.Baidu Comate的简介 根据官网的介绍&#xff0c;我们了解到B…

模型onnx转ncnn小记

前期准备 Netron 模型准备&#xff1a;onnx模型,这里使用模型face【det_10g.onnx】 大佬文档引用&#xff1a;手工优化ncnn模型结构 - 知乎 ncnn算子描述参考&#xff1a;ncnn 算子操作描述-CSDN博客 模型优化 安装 pip install onnx-simplifier 先把我要转的模型优化合…

全网最详细的Python自动化测试(unittest框架)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Web 功能以及源码讲解

Web 功能以及语言讲解 培训、环境、资料、考证 公众号&#xff1a;Geek极安云科 网络安全群&#xff1a;624032112 网络系统管理群&#xff1a;223627079 网络建设与运维群&#xff1a;870959784 移动应用开发群&#xff1a;548238632 短视频制作群&#xff1a; 744125867极…

【6D位姿估计】FoundationPose 跑通demo 训练记录

前言 本文记录在FoundationPose中&#xff0c;跑通基于CAD模型为输入的demo&#xff0c;输出位姿信息&#xff0c;可视化结果。 然后分享NeRF物体重建部分的训练&#xff0c;以及RGBD图为输入的demo。 1、搭建环境 方案1&#xff1a;基于docker镜像&#xff08;推荐&#xf…

电脑windows系统压缩解压软件-Bandizip

一、软件功能 Bandizip是一款功能强大的压缩和解压缩软件&#xff0c;具有快速拖放、高速压缩、多核心支持以及广泛的文件格式支持等特点。 Bandizip软件的功能主要包括&#xff1a; 1. 支持多种文件格式 Bandizip可以处理多种压缩文件格式&#xff0c;包括ZIP, 7Z, RAR, A…

Win10环境下yolov8快速配置与测试-详细

0.0 说明 参考黄家驹的Win10 环境下YOLO V8部署&#xff0c;遇到一些问题&#xff0c;并解决实现&#xff0c;记录如下: 斜线字体是原博客中的创作 0.1 参考链接 https://blog.csdn.net/m0_72734364/article/details/128865904 1 Windows10下yolov8 tensorrt模型加速部署 …

苍穹外卖Day06笔记

疯玩了一个月&#xff0c;效率好低&#xff0c;今天开始捡起来苍穹外卖~ 1. 为什么不需要单独引入HttpClient的dependency&#xff1f; 因为我们在sky-common的pom.xml中已经引入了aliyun-sdk-oss的依赖&#xff0c;而这个依赖低层就引入了httpclinet的依赖&#xff0c;根据依…

Centos7网络处理name or service not known

1、编辑->虚拟网络编辑器 2、查看本机的ip 3、 /etc/sysconfig/network-scripts/ 查看文件夹下面的 ifcfg-eth33 后面的33可能不一样 vi /etc/resolv.conf 编辑文件添加以下DNS nameserver 114.114.114.114 4、设置本机的网络 5、ping www.baidu.com 先重启…

linux调试

文章目录 1. 使用打印来调试1.1 重定向1.2 标准预定义宏1.3 日志代码 2. 内核异常2.1 内核打印2.1.1 打印级别2.1.2 跟踪异常2.1.3 动态打印2.1.4 RAM console 2.2 OOPS2.2.1 有源代码的情况2.2.2 没有源代码的情况 3 查看日志4 工具调试 1. 使用打印来调试 1.1 重定向 2>…

Django之创建Model以及后台管理

一&#xff0c;创建项目App python manage.py startapp App 二&#xff0c;在App.models.py中创建类&#xff0c;以下是示例 class UserModel(models.Model):uid models.AutoField(primary_keyTrue, auto_createdTrue)name models.CharField(max_length10, uniqueTrue, db…

【C++11新特性】lambda表达式和应用场景

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…
最新文章