【TS】TypeScript基本使用

什么是TypeScript?

是一种编程语言,是JavaScript的超集,过添加静态类型接口模块等功能,使得在大型应用程序中更容易进行维护和扩展,可以编译成纯JavaScript

静态类型和动态类型有什么区别?

静态类型动态类型
定义编译阶段进行类型检查的类型系统,通过类型注解或推断来确定变量、参数和返回值的类型。运行时才确定变量的类型,允许同一个变量在不同时间引用不同类型的值
特点在编码阶段就发现大部分类型错误运行时可以根据上下文或条件动态地改变变量的类型
优势可以在编辑器或 IDE 中实现代码提示、自动补全和类型检查,帮助开发者减少错误并提高代码质量更大的灵活性,快速,适用于一些需要频繁变化类型的场景

 类型断言是什么?

显式告诉编译器变量的类型,使用 <type> 或 as type 语法实现的

let strLength: number = (someValue as string).length;
let strLength: number = (<string>someValue).length;

泛型是什么?

允许创建可与各种类型一起使用的可重用组件或函数

function identity<T>(arg: T): T {return arg;
}
const result1 = identity<number>(42); // Explicitly specifying the type
const result2 = identity('hello'); // Inferring the type

"keyof"、"typeof"、 "in"、"infer"关键字是什么?

  • keyof:用于获取对象类型的键的并集
  • typeof:用于获取值的类型
  • in:检查属性键是否存在于从“keyof”获得的键的并集中
  • infer:从条件类型中的另一种类型推断出类型
interface Person {name: string;age: number;
}
type PersonKeys = keyof Person; // Result: "name" | "age"
const john = { name: 'John', age: 30 };
type JohnType = typeof john; // Result: { name: string, age: number }
type CheckKey<T, K extends keyof T> = K extends 'name' ? true : false;
interface Person {name: string;age: number;
}
type IsNameKey = CheckKey<Person, 'name'>; // Result: true
type IsCityKey = CheckKey<Person, 'city'>; // Result: false
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function add(a: number, b: number): number {return a + b;
}
type AddReturnType = ReturnType<typeof add>; // Result: number

什么是条件类型?

允许创建依赖于条件的类型,用于根据类型之间的关系执行类型推断

type IsString<T> = T extends string ? true : false;
type CheckString = IsString<string>; // Result: true
type CheckNumber = IsString<number>; // Result: false

什么是映射类型?

允许通过将属性映射到新类型来基于现有类型创建新类型

interface Person {name: string;age: number;
}
type PersonWithOptionalProperties = { [K in keyof Person]?: Person[K] };
const john: Person = { name: 'John', age: 30 };
const johnWithOptionalProperties: PersonWithOptionalProperties = { name: 'John' };

 什么是条件映射类型?

将条件类型和映射类型结合起来,根据条件执行类型转换,根据现有类型的属性创建动态类型

interface Person {name: string;age: number;
}
type MappedConditional<T> = {[K in keyof T]: T[K] extends number ? string : T[K];
};
const john: MappedConditional<Person> = { name: 'John', age: '30' };

"mixins"是什么?

将某个类与一个或多个其他类组合来向该类添加行为

class Printable {print() {console.log(this.toString());}
}
class MyObject {constructor(private name: string) {}toString() {return `Object: ${this.name}`;}
}
interface MyObject extends Printable {}
const myObj = new MyObject('example');
myObj.print(); // Output: "Object: example"

Printable 类充当 mixin,将 print 方法添加到 MyObject 类

"装饰器"是什么?

允许、修改类、方法或属性的行为,使用 @decoratorName 语法声明并在运行时执行

function MyClassDecorator<T extends { new (...args: any[]): {} }>(constructor: T) {return class extends constructor {newProperty = 'decorated property';hello = 'overridden';};
}
@MyClassDecorator
class MyClass {hello: string;constructor() {this.hello = 'world';}
}
const myClassInstance = new MyClass();
console.log(myClassInstance.hello); // Output: "overridden"
console.log((myClassInstance as any).newProperty); // Output: "decorated property"

”键重新映射“、"值重新映射"是什么?

interface Person {name: string;age: number;
}
// 键重新映射
type MappedPerson = { [K in keyof Person as `new_${K}`]: Person[K] };
const john: MappedPerson = { new_name: 'John', new_age: 30 };// 值重新映射
type ValueRemapped<T> = T extends 'a' ? 'x' : T extends 'b' ? 'y' : 'z';
type Result = ValueRemapped<'a' | 'b' | 'c'>; // Result: 'x' | 'y' | 'z'

"Pick"、"Omit"、"Exclude"、"部分"、"只读"实用程序类型是什么?

  • Pick:通过从现有类型中选择特定属性来创建新类型
  • Omit:通过从现有类型中排除特定属性来创建新类型
  • Exclude: 通过从联合中排除某些类型来创建新类型
  • 部分: 使现有类型的所有属性成为可选
  • 只读:使现有类型的所有属性变为只读

interface Person {name: string;age: number;city: string;
}// Pick
type PersonInfo = Pick<Person, 'name' | 'age'>;
const john: PersonInfo = { name: 'John', age: 30 };// Omit
type PersonWithoutCity = Omit<Person, 'city'>;
const john: PersonWithoutCity = { name: 'John', age: 30 };// Exclude
type Color = 'red' | 'green' | 'blue';
type PrimaryColors = Exclude<Color, 'green' | 'blue'>;
const primary: PrimaryColors = 'red'; // Okay
const invalidColor: PrimaryColors = 'green'; // Error: Type '"green"' is not assignable to type 'PrimaryColors'.// 可选
interface Person {name: string;age: number;
}
type PartialPerson = Partial<Person>;
const john: PartialPerson = { name: 'John' };// 只读
interface Person {readonly name: string;age: number;
}
const john: Readonly<Person> = { name: 'John', age: 30 };
john.age = 31; // Error: Cannot assign to 'age' because it is a read-only property.

 "模板文字类型"是什么?

使用模板文字语法来操作类型中的字符串

type Greeting<T extends string> = `Hello, ${T}!`;
type GreetJohn = Greeting<'John'>; // Result: "Hello, John!"
type GreetJane = Greeting<'Jane'>; // Result: "Hello, Jane!"

"keyof T extends K"构造是什么? 

type FilterProperties<T, K> = {[P in keyof T as T[P] extends K ? P : never]: T[P];
};
interface Person {name: string;age: number;email: string;
}
type StringProperties = FilterProperties<Person, string>;
// Result: {
//   name: string;
//   email: string;
// }
type NumberProperties = FilterProperties<Person, number>;
// Result: {
//   age: number;
// }

"私有"、”受保护“访问修饰符是什么?

私有:Private

受保护:protected

类型

基本类型

类型使用
布尔
let isDone: boolean = false;
数字
let decLiteral: number = 6;
字符串
let name: string = "bob";
Null
let u: undefined = undefined;
Undefined
let n: null = null;

复合类型

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

元组Tuple

let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error
枚举enum
enum Color {Red=1, Green, Blue};
let c: Color = Color.Green;
let colorName: string = Color[2]; // Green

对象类型

object非原始类型
interface描述对象结构,可复用

函数类型

任意值any
let notSure: any = 4;
空值void
function warnUser(): void {alert("This is my warning message");
}// void类型变量,只能是undefined和null
let unusable: void = undefined;
Never

会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型

function error(message: string): never {throw new Error(message);
}

高级类型

交叉类型

interface A {a(): void;
}
interface B {b(): void;
}
type C = A & B; // 表示同时具备 A 和 B 的特性

联合类型

let myVar: string | number;
myVar = "Hello"; // 合法
myVar = 123; // 合法

泛型generic

定义:在定义函数、类或接口时使用类型参数的方式,以增加代码的灵活性和重用性

泛型变量

function loggingIdentity<T>(arg: T[]): T[] {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}function loggingIdentity<T>(arg: Array<T>): Array<T> {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}

泛型函数loggingIdentity,接收类型参数T和参数arg(它是个元素类型是T的数组),并返回元素类型是T的数组

 泛型类型

interface GenericIdentityFn<T> {(arg: T): T;
}function identity<T>(arg: T): T {return arg;
}let myIdentity: GenericIdentityFn<number> = identity;

泛型类 

class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;
}let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型约束 extends

对类型参数做一定的限制

// extends对传入的参数做了一个限制,就是entities的每一项可以是一个对象,但是必须含有类型为string的cname属性
function getCnames<T extends { name: string }>(entities: T[]):string[] {return entities.map(entity => entity.cname)
}

 枚举enum

定义:对数字值集合进行命名的方式,增加代码可读性

enum FileAccess {// constant membersNone,Read    = 1 << 1,Write   = 1 << 2,ReadWrite  = Read | Write,// computed memberG = "123".length
}

枚举和常量枚举的区别:

  • 枚举可以包含计算得出的值,而常量枚举则在编译阶段被删除,并且不能包含计算得出的值,它只能包含常量成员。

  • 常量枚举在编译后会被删除,而普通枚举会生成真实的对象。

类型声明和类型推断的区别

// 类型声明:显示为变量或者函数指定类型
let x: number;
x = 10;
// 类型推断:根据语句右侧的值自动推断类型
let y = 20; // TypeScript会自动推断y的类型为number

可控类型和undefined类型使用

let numberOrNull: number | null = 10; 
numberOrNull = null; // 可以赋值为null let stringOrUndefined: string | undefined = "Hello"; 
stringOrUndefined = undefined; // 可以赋值为undefined

 接口interface

用于描述对象的形状的结构化类型。它定义了对象应该包含哪些属性和方法。在TypeScript中,接口可以用来约束对象的结构,以提高代码的可读性和维护性。

接口和类型别名的区别:

  • 接口定义了一个契约,描述了对象的形状(属性和方法),以便在多个地方共享。它可以被类、对象和函数实现。
  • 类型别名给一个类型起了一个新名字,便于在多处使用。它可以用于原始值、联合类型、交叉类型等。与接口不同,类型别名可以用于原始类型、联合类型、交叉类型等,而且还可以为任意类型指定名字。
类型使用
可选属性
只读属性

只读,不可更改

函数类型
可索引的类型

有两种索引签名:字符串和数字

类类型
类静态与实例
继承(单、多个)
混合类型
接口继承类

命名空间(Namespace)和模块(Module)

命名空间模块
定义将具有相似功能或者属性的类、接口进行分组,避免全局命名冲突将相关代码组织到单独的文件,使用module来导入、导出这些文件中的功能
作用全局范围内组织代码的方式,防止命名冲突组织代码,多个文件共享代码
示例

类型守卫(Type Guards)

在特定的作用域内缩小变量的范围,以确保正确推断类型。

索引类型(Index Types)

创建具有动态属性名称的对象,并且能够根据已知的键来获取相应的属性类型

优点:

1、动态属性访问

在处理动态属性名的对象时,可以使用索引类型来实现类型安全的属性访问。例如,当从服务器返回的 JSON 数据中提取属性时,可以利用索引类型来确保属性名存在并获取其对应的类型

2、代码重用

当需要创建通用函数来操作对象属性时,索引类型可以帮助我们实现更加通用和灵活的代码。例如,一个通用的函数可能需要根据传入的属性名称获取属性值,并进行特定的处理

3、动态扩展对象

当需要处理来自外部来源(比如 API 响应或数据库查询)的动态数据时,索引类型可以让我们轻松地处理这种情况,而不必为每个可能的属性手动定义类型。

4、类型安全性

索引类型可以增强代码的类型安全性,因为它们可以捕获可能的属性名拼写错误或键不存在的情况。

5、映射类型

TypeScript 还提供了映射类型(Mapped Types)的概念,它们利用索引类型可以根据现有类型自动生成新类型。这在创建新类型时非常有用,特别是当需要在现有类型的基础上添加或修改属性时。

 const、readonly的区别

  • const:声明常量值,赋值后,不可修改,常用于常数或固定值
  • readonly:在声明时或者构造函数中,被赋值,赋值后,不能修改;通常用在表示对象的某些属性是只读,防止外部修改
const PI = 3.14;
PI = 3.14159; // Error: 无法重新分配常量class Person {readonly name: string;constructor(name: string) {this.name = name; // 可以在构造函数中赋值}
}let person = new Person("Alice");
person.name = "Bob"; // Error: 无法分配到"name",因为它是只读属性

any类型的作用,缺点

允许编写代码时不指定具体的类型,从而可以接受任何类型的值,放弃了静态类型检查

使用场景

  • 不确定变量或者表达式具体类型,可用any
  • 与动态类型的Js代码交互时,可用来出来这些动态类型的值

缺点

1、降低可读性

let data: any;
// 代码中的使用方式
data.someUnknownMethod(); // 在编译阶段不会报错,但实际上可能是一个错误

2、可能会导致编译不报错,运行时错误

let myVariable: any = 123;
myVariable.toUpperCase(); // 在编译阶段不会报错,但在运行时会引发错误

3、类型安全受损

function add(x: any, y: any): any {return x + y; // 编译器无法推断返回值的具体类型
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 命令之只提交文件的部分更改

git 命令之只提交文件的部分更改 有时&#xff0c;我们在一个文件中进行了多个更改&#xff0c;但只想提交其中的一部分更改。这时可以使用 使用 git add -p 命令 Git add -p命令允许我们选择并添加文件中的特定更改。它将会显示一个交互式界面&#xff0c;显示出文件中的每个更…

深度学习网络模型 MobileNet系列MobileNet V1、MobileNet V2、MobileNet V3网络详解以及pytorch代码复现

深度学习网络模型 MobileNet系列MobileNet V1、MobileNet V2、MobileNet V3网络详解以及pytorch代码复现 1、DW卷积与普通卷积计算量对比DW与PW计算量普通卷积计算量计算量对比 2、MobileNet V1MobileNet V1网络结构MobileNet V1网络结构代码 3、MobileNet V2倒残差结构模块倒残…

[极客大挑战 2019]BabySQL--详细解析

信息搜集 进入界面&#xff1a; 输入用户名为admin&#xff0c;密码随便输一个&#xff1a; 发现是GET传参&#xff0c;有username和password两个传参点。 我们测试一下password点位能不能注入&#xff1a; 单引号闭合报错&#xff0c;根据报错信息&#xff0c;我们可以判断…

C 语言面向对象

面向对象的基本特性&#xff1a;封装&#xff0c;继承&#xff0c;多态 1.0 面向过程概念 当我们在编写程序时&#xff0c;通常采用以下步骤&#xff1a; 1. 将问题的解法分解成若干步骤 2. 使用函数分别实现这些步骤 3. 依次调用这些函数 这种编程风格的被称作 面向过程…

VMware16安装macOS12【详细教程】

因为在应用上线IOS应用商店时&#xff0c;需要用到mac系统进行&#xff0c;于是就在VMware16pro虚拟机进行安装macOS12系统&#xff0c;安装的过程做了一个记录&#xff0c;希望对你有所帮助&#xff01; 前言 首先需要下载好下面工具&#xff1a; VMware workstation pro 16…

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析

在数字科技日新月异的今天&#xff0c;视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台&#xff0c;提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务&#xff0c;广泛应用于…

【Python】分割秘籍!掌握split()方法,让你的字符串处理轻松无敌!

在Python开发中&#xff0c;字符串处理是最常见也是最基础的任务之一。而在众多字符串操作方法中&#xff0c;split()函数无疑是最为重要和常用的一个。无论你是Python新手&#xff0c;还是经验丰富的开发者&#xff0c;深入理解并熟练运用split()方法&#xff0c;都将大大提升…

从 Llama 1 到 3.1:Llama 模型架构演进详解

编者按&#xff1a; 面对 Llama 模型家族的持续更新&#xff0c;您是否想要了解它们之间的关键区别和实际性能表现&#xff1f;本文将探讨 Llama 系列模型的架构演变&#xff0c;梳理了 Llama 模型从 1.0 到 3.1 的完整演进历程&#xff0c;深入剖析了每个版本的技术创新&#…

【Qt】QComboBox设置默认显示为空

需求 使用QComboBox&#xff0c;遇到一个小需求是&#xff0c;想要设置未点击出下拉列表时&#xff0c;内容显示为空。并且不想在下拉列表中添加一个空条目。 实现 使用setPlaceholderText()接口。我们先来看下帮助文档&#xff1a; 这里说的是&#xff0c;placeholderText是…

mysql根据日期查询没有的日期也要显示数据

先查询出日期数据(当前日期往前推12个月) select bb.datefrom (select num : num 1,date_format(adddate(date_sub(date_sub(curdate(),interval 12 month),interval 1 month),interval num month), %Y-%m) as datefrom mysql.help_topic,(select num : 0) as twhere addd…

非root用户安装CUDA

1.使用nvidia-smi查看当前驱动支持的最高CUDA版本&#xff1a; 表示当前驱动最多支持cuda12.1 2.进入cuda安装界面&#xff0c;https://developer.nvidia.com/cuda-toolkit-archive&#xff0c;选择想要安装的版本&#xff0c;例如想要安装CUDA11.4&#xff1a; 如果需要查看ub…

Halo 正式开源: 使用可穿戴设备进行开源健康追踪

在飞速发展的可穿戴技术领域&#xff0c;我们正处于一个十字路口——市场上充斥着各式时尚、功能丰富的设备&#xff0c;声称能够彻底改变我们对健康和健身的方式。 然而&#xff0c;在这些光鲜的外观和营销宣传背后&#xff0c;隐藏着一个令人担忧的现实&#xff1a;大多数这些…

Python 爬虫从入门到(不)入狱学习笔记

爬虫的流程&#xff1a;从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战&#xff1a;豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据&#xff08;略&#xff09; 一般爬虫的基…

黄仁勋:人形机器人在内,仅有三种机器人有望实现大规模生产

11月23日&#xff0c;芯片巨头、AI时代“卖铲人”和最大受益者、全球市值最高【英伟达】创始人兼CEO黄仁勋在香港科技大学被授予工程学荣誉博士学位&#xff1b;并与香港科技大学校董会主席沈向洋展开深刻对话&#xff0c;涉及人工智能&#xff08;AI&#xff09;、计算力、领导…

【Linux学习】【Ubuntu入门】2-3 make工具和makefile引入

1.使用命令新建三个.c文件vi main.c&#xff0c;vi input.c&#xff0c;vi caclcu.c&#xff0c;两个.h文件vi input.h&#xff0c;vi caclcu.h 2.vi Makefile&#xff1a;新建Makefile文件&#xff0c;输入一下内容 注意&#xff1a;命令列表中每条命令前用TAB键&#xff0c;不…

wsl2的Ubuntu18.04安装ros和anaconda

参考&#xff1a;超详细 WSL2 安装 ros 和 anaconda_wsl2安装anaconda-CSDN博客 一.安装ros 1. 更换系统源 输入 wget http://fishros.com/install -O fishros && . fishros 和上面的链接一样&#xff0c;依次输入5-2-1 2. 安装ros 输入 wget http://fishros.c…

1-golang_org_x_crypto_bcrypt测试 --go开源库测试

1.实例测试 package mainimport ("fmt""golang.org/x/crypto/bcrypt" )func main() {password : []byte("mysecretpassword")hashedPassword, err : bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)if err ! nil {fmt.Println(err)…

【FPGA】Verilog:利用 4 个串行输入- 串行输出的 D 触发器实现 Shift_register

0x00 什么是寄存器 寄存器(Register)是顺序逻辑电路中使用的基本组成部分之一。寄存器用于在数字系统中存储和处理数据。寄存器通常由位(bit)构成,每个位可以存储一个0或1的值。通过寄存器,可以设计出计数器、加法器等各种数据处理电路。 0x01 寄存器的种类 基于 D 触发…

用 Python 从零开始创建神经网络(十):优化器(Optimizers)(持续更新中...)

优化器&#xff08;Optimizers&#xff09; 引言1. 随机梯度下降/Stochastic Gradient Descent (SGD)2. 学习率&#xff08;Learning Rate&#xff09;3. 学习率衰减&#xff08;Learning Rate Decay&#xff09;4. 带动量的随机梯度下降法&#xff08;Stochastic Gradient Des…

利用c语言详细介绍下栈的实现

数据结构中&#xff0c;栈是一种线性结构&#xff0c;数据元素遵循后进先出的原则。栈的一端为栈顶&#xff0c;一端为栈底或栈尾&#xff0c;数据只在栈顶端进行操作。新插入数据称为入栈或者压栈&#xff0c;删除数据叫做出栈或者退栈。 一、图文介绍 我们通过建立一个stack…