TypeScript 基础使用和相关问题

  1. tsconfig.json 配置文件
{"compilerOptions": {"target": "esnext","jsx": "preserve","jsxImportSource": "vue","lib": ["esnext", "dom"],"useDefineForClassFields": true,"experimentalDecorators": true,// baseUrl 用来告诉编译器到哪里去查找模块,使用非相对模块时必须配置此项"baseUrl": ".","module": "esnext","moduleResolution": "bundler",// 非相对模块导入的路径映射配置,根据 baseUrl 配置进行路径计算,与 vite.config 中 alias 配置同步"paths": {"@/*": ["src/*"],"@@/*": ["src/common/*"]},"resolveJsonModule": true,"types": ["vite/client", "element-plus/global"],// 允许导入 .ts .mts .tsx 拓展名的文件"allowImportingTsExtensions": true,// 允许 JS"allowJs": true,// TS 严格模式"strict": true,"importHelpers": true,// 不输出任何编译后的文件,只进行类型检查"noEmit": true,"sourceMap": true,"allowSyntheticDefaultImports": true,"esModuleInterop": true,"isolatedModules": true,"skipLibCheck": true},// 需要被编译的文件列表"include": ["**/*.ts", "**/*.tsx", "**/*.vue", "**/*.d.ts"],// 从编译中排除的文件列表"exclude": ["node_modules", "dist"]
}
  1. 创建一个值为字符串的变量
let message: string = 'Hello TypeScript'
  1. 布尔值
let isDone:boolean = false;
  1. 数字
let decimal: number = 6;
let hex: number = 0xf00d;
let binay: number = 0b1010;
let octal: number = 0O744;
  1. 数组
let list: number[] = [1,2,3];
// 使用泛型数组类型:
let list1: Array<number> = [4,5,6];
  1. 元组
let x: [string, number];
x = ['hello', 10]
  1. 枚举
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
  1. Any
// 不确定变量类型时,可以使用 any 类型:
let notSure: any = 4;
notSure = 'maybe a string instead';
notSure = false;
  1. Void
// 用于表示没有任何类型,常用于没有返回值的函数
function warnUser(): void {console.log('this is a viod log')
}
  1. Null 和 Undefined
let u: undefined = undefined;
let n: null = null;
  1. Never
// 表示那些用不存在的值的类型,例如:永远不会返回的函数表达式或箭头函数的返回值类型:
function error(message: string): never {throw new Error(message)
}
  1. Object
// 表示非原始类型
declare function ceeate(o: object | null): void;
create({ prop: 0 })
create(null);
  1. 接口
/*** 接口是 TypeScript 中的核心原则之一,用于定义对象的类型。* 接口能够描述一个对象的形状,能够检查对象是否符合特定的结构。* 示例如下:*/
interface LabelledValue {label: string;
}function printLabel(labelledObj: LabelledValue) {console.log(labelledObj.label);
}let myObj = { size: 10, label: 'Size 10 Object' };printLabel(myObj);
/*** 小结:LabelledValue 接口定义了一个 label 属性,并且 printLabel 函数期望一个实现了 LabelledValue 接口的对象作为参数。即使 myObj 有其他属性,但只要它至少有一个 label 属性,TS 就会认为它是合法的。*/
  1. 可选属性
// 可选属性接口允许一些属性存在,也允许一些属性不存在:
interface SquareConfig {color?: string;width?: number;
}function createSquare(config: SquareConfig): {color: string, area: number} {let newSquare = { color: 'white', area: 100 };if(config.color) {newSquare.color = config.color;}if(config.width) {newSquare.area = config.width * config.width;}return newSquare;
}let mySquare = createSquare({ color: 'black' })
// 小结:SquareConfig 接口定义了 color 和 width 可选属性。CreateSquare 函数根据传入 config 对象动态地创建一个新的对象。
  1. 只读属性
// 一些属性可以在对象刚刚船舰的时候修改其值,而在此之后将是只读的
interface Point {readonly x: number;readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
pi.x = 5; // 一旦赋值就会报错误,不能改变只读属性
  1. 函数类型
// 接口也可以描述函数类型
interface SeachFunc {(source: string, subString: string): beelean;
}let mySearch: SearchFunc;
mySearch = function (source: string, subString: string) {let result = source.Search(subString);return result > -1;
};
  1. 可索引类型
// 接口可以描述那些能够通过索引得到某种类型的对象,这在对象上可以用数字索引或字符串索引
interface StringArray {[index: number]: string;
}let myArray: StringArray;
myArray = ['Bob', 'Fred'];let myStr: string = myArray[0];
// StringArray 接口描述了具有数字索引的数组类型,并且返回值是字符串类型
  1. 类-简单类
class Greeter {greeting: string;constructor(message: string) {this.greeting = message;}greet() {return 'Hello, ' + this.greeting;}
}
let greeter = new Greeter('world');
// Greeter 类有一个 greeting 属性和一个 greet 方法, greet 方法返回一个字符串。
  1. 类-继承
// 类可以扩展其他类,一个类可以继承另一个类的属性和方法;
class Animal {name: string;constructor(theName: string) {this.name = theName;}move(distanceInMeters: number = 0) {console.log(`${this.name} moved ${distanceInMeters}m.`);}
}class Snke extends Animal {constructor(name: string) {super(name);}move(distanceInMeters = 5) {console.log('Slithering...');super.move(distanceInMeters);}
}let sam = new Snake('Sammy the Python');
sam.move();
// Snke 类扩展了 Animal 类,并且重写了 move 方法.
  1. 类-公共,私有与受保护修饰符
// TS 中的成员默认是公共的,也可以用 private 修饰符将成员标记为私有的:
class Animal {private name: string;constructor(theName: string) {this.name = theName;}
}new Animal('Cat').name; // 错误: name 是私有的// 可以使用 protected 修饰符声明受保护的成员,这些成员只能在类本身及其子类中访问:
class Person {protected name: string; // 受保护的成员,只能在类本身及其子类访问constructor(name: string) {this.name = name;}
}class Employee extends Person {private department: string;constructor(name: string, department: string) {super(name);this.department = department;}getElevatorPitch() {return `Hello, my name is ${this.name} and I work in ${this.department}.`}
}let howard = new Employee('Howard', 'Sales');
console.log(howard.getElevatorPitch()); //有效
console.log(howard.name); // 错误
  1. 类-readonly 修饰符
// readonly 关键字将属性设置为只读
class Octopus {readonly name: string;readonly numberOfLegs: number = 0;constructor(theName: string) {this.name = theName;}
}
let dad = new Octopus('Man width the 8 strong legs');
dad.name = 'Man with the 3'; // 错误 name是只读的;
  1. 类-存取器
// 支持通过 get 和 set 关键字来定义存取器
class Employee {private _fullName: string; // 设置私有属性get fullName(): string {return this._fullName;}set fullName(newName: string) {this._fullName = newName;}
}let employee = new Employee();
employee.fullName = 'Bob Smith';
console.log(employee.fullName)
// Employee 类有一个私有属性 _fullName, 并且通过存取器来设置和获取它的值。
  1. 函数-(和JavaScript函数类似,但在参数和返回类型上提供了更多类型的检查)
  2. 函数类型
// 为函数的参数和返回值指定类型
function add(x: number, y: number): number {return x + y;
}let myAdd:(x: number, y: number) => number = function (x: number, y: number): number {return x + y;
}
  1. 函数-可选参数和默认参数
// 可以通过在参数名旁使用 ? 来实现可选参数
function buildName(firstName: string, lastName?: string): string {if(lastName) {return firstName + ' ' + lastName;} else {return firstName;}
}let result1 = buildName('Bob'); // 有效
let result2 = buildName('Bob', 'Adams'); // 有效
// 还可以为参数提供默认值
function buildName(firstName: string, lastNAme = 'Smith'): string {return firstName + ' ' + lastName;
}let result1 = buildName('Bob'); // 有效 返回 'Bob Smith'
let result2 = buildName('Bob', 'Adams'); // 有效 返回 'Bob Adams' 
  1. 函数-剩余参数
// 可以使用 ... 语法将所有参数收集到一个变量中
function buildName(firstName: string, ...restOfName: string[]) {return firstNAme + '' + resetOfName.join('');
}let employeeName = buildName('Joseph', 'Samuel', 'Lucas', 'MackinZie');
  1. 函数-this和箭头函数
// 在 TypeScript 中, this 的值取决于函数调用的位置,可以使用箭头来正确的捕获this 的值
let dect = {suits: ['hearts', 'spades', 'cluds', 'diamonds'],cards: Array(52),createCardPicker: function () {return () => {let pickedCard = Math.floor(Math.random() * 52);let pickedSuit = Math.floor(pickedCard / 13);return { suit: this.suits[pickedSuit], card: pickedCard % 13 };};};
};let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();console.log('card:', pickedCard.card)
console.log('suit:', pickedCard.suit)
// 例子中,箭头函数不会创建自己的 this, 它会捕获 deck 对象的 this 值。
  1. 泛型-泛型函数
function identity<T>(arg: T): T {return arg;
}let output = identity<string>('mtstring'); // 手动指定类型
let output2 = identity('mystring'); // 类型推断
  1. 泛型-泛型接口
interface CenericIdentityFn<T> {(arg: T): T;
}function identity<T>(arg: T): T {return arg;
}let myIdentity: GenericIdentityFn<number> = identity;
// 上述例子中,GenericIdentityFn 接口描述了一个泛型函数类型,并且 myIdentity 是一个特定类型的泛型函数。
  1. 泛型- 泛型类
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;
}
// GenericNumber 是一个泛型类,它可以处理任意类型的数字 
  1. 泛型-泛型约束
// 想要限制某种类型的泛型函数,就可以使用泛型约束
interface Lengthwise {length: number;
}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length)return arg;
}loggingIdentity({length: 10, value: 2});
// loggingIdentity 函数要求传入的参数必须有 length 属性。
  1. 泛型-在泛型约束中使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K) {return obj[key];
}let x = {a: 1, b: 2, c: 3, d: 4};getProperty(x, 'a') // 有效
getProperty(x: 'm') // 错误:类型‘m’的参数不能赋给类型"a" | "b" | "c" | "d" 的参数
// 上述例子中,getProperty 函数接收一个对象和一个属性名称,并返回该属性的值,K被约束为 T的属性名称。
  1. 类型推断
  • TypeScript 能够根据代码中的一些简单的规则推断变量的类型。如果变量声明时没有指定类型,TypeScript会自动推断出一个类型
  1. 类型推断-基础示例
let x = 3; // x 被推断为 number 类型
  1. 类型推断-最佳通用类型
// 当需要从多个表达式中推断类型时, TypeScript 会选择最合适的通用类型
let x = [0, 1, null]; // x 的类型推断为(number | null)
  1. 类型兼容性
  • TypeScript 中的类型兼容性是基于结构子类型的。结构类型系统是基于类型的成员来确定类型的兼容性。
  1. 类型兼容性-接口兼容性
interface Named {name: string;
}class Person {name: string;
}let p: Named;
p = new Person(); // 正确 因为 Person 有一个兼容的 name 属性
  1. 类型兼容性-函数兼容性
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;y = x; // OK
x = y; // Err
  1. 高级类型
  • TypeScript 提供了许多高级类型操作,可以在编辑复杂类型定义时提供更强的灵活性
  1. 高级类型-交叉类型
// 交叉类型 & 是将多个类型合并为一个类型
function extend<T, U>(first: T, second: U): T & U {let result = <T & U>{};for(let id in first) {(result as any)[id] = (first as any)[id]}for(let id in second) {if(!result.hasOwnProperty(id)) {(result as any)[id] = (second as any)[id];}}return result;
}let x = extend({ a: 'hello' }, { b: 42 });
let a = x.a; // string
let b = x.b; // number
  1. 高级类型-联合类型
  • 联合类型 | 表示一个值可以是几种类型之一
function padLeft(value: string, padding: string | number) {if(typeof padding === 'number') {return Array(padding + 1).join(' ') + value;}if(typeof padding === 'string') {return padding + value;}throw new Error(`Expected string or number, got ${typeof padding}.`);
}padLeft('Hello world', 4); // 返回 "    Hello world"
padLeft('Hello world', '>>>'); // 返回 ">>>Hello world"
  1. 高级类型- 类型别名
  • 类型别名可以类型起一个新名字
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name {if(typeof n === 'string') {return n;} else {return n();}
}
  1. 高级类型-字面量类型
  • 字面量类型约束一个变量的值只能是某个特定的值
type Easing = 'ease-in' | 'ease-out' | 'ease-in-out';class UIElement {animate(dx: number, dy: number, easing: Easing) {if(easing === 'ease-in') {// do something...} else if(easing === 'ease-out') {// do something...} else if(easing === 'ease-in-out') {// do something} else {throw new Error('参数必须是ease-in, ease-out,ease-in-out')}}
}let button = new UIElement();
button.animate(0, 0, 'ease-in'); // ok
button.animate(0, 0, 'unesay'); // error
  1. 装饰器
  • 装饰器是一个特殊类型的声明,能够被附加到类声明、方法、访问器、属性或参数上,装饰器使用 @expressoon 这种形式, expression必须求值为一个函数,它将在运行时被调用,被装饰的声明信息作为参数传入。
  1. 装饰器-类装饰器
function sealed(constructor: Function) {Object.seal(constructor);Object.seal(constructor.prototype);
}@sealed
class Greeter {greeting: string;constructor(message: string) {this.greeting = message;}greet() {return 'Hellow, ' + this.greeting;}
}
  1. 装饰器-方法装饰器
function enumerable(value: boolean) {return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {descriptor.enumerable = value;}
}class Greeter {greeting: string;constructor(message: string) {this.greeting = message;}@enumerable(false)greet() {return 'Hello, ' + this.greeting;}
}
  1. 编译选项
  • TypeScript 编译器 可以通过命令行参数和 tsconfig.json 文件进行配置。
  • tsconfig.json 文件用于配置 TypeScript 项目,示例如下:
{"compilerOptions": {"target": "es6","module": "commonjs","strict": true,"esModuleInterop": true,"skipLibCheck": true,"forceConsistentCasingInFileNames": true},"include": ["src/**/*"],"exclude": ["node_modules", "**/*.spec.ts"]
}
  1. 常见问题与最佳时间
  2. 如何进行类型定义
  • 解答: 在 TypeScript 中进行类型定义时,推荐尽量使用接口,因为接口可以被类实现和扩展,并且更加灵活和易于阅读。
  1. 何时使用类型断言?
  • 解答: 类型断言用于告诉编译器某个值的具体类型:
let someValue: any = 'this is a string';
let strLength: number = (someValue as string).length;
// 尽量避免过度使用类型断言,因为它可能隐藏潜在的类型错误
  1. 如何处理第三方库的类型定义
  • 解答:可以使用 DefinitelyTyped 项目提供的类型定义文件
npm install @type/jquery --save-dev
  • 这样就可以在 TypeScript 项目中使用 jQuery 的类型定义文件
  1. 如何调试 TypeScript 代码
  • 解答: 可以通过生成 Source Map 文件来调试 TypeScript 代码
{"compilerOptions": {"sourceMap": true}
}
// 这样就可以在调试工具中直接看到  TypeScript 代码,并且设置断点进行调试
  1. 如何提高代码质量
  • 启用严格模式:在 tsconfig.json 中启用 strict选项
  • 使用代码格式化工具, 如 Prettier 来保持代码风格一致。
  • 使用代码静态分析工具: 如 ESLint 来发现和修复代码中的潜在问题
  • 编写单元测试: 确保代码的正确性和稳定性

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

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

相关文章

leetcode-分割等和子集

本题涉及到的是01背包问题&#xff0c;我将从两种解决背包问题的思路写出题解 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#…

企业级流程架构设计思路-基于价值链的流程架构

获取更多企业流程资料 纸上得来终觉浅&#xff0c;绝知此事要躬行 一.企业流程分级规则定义 1.流程分类分级的总体原则 2.完整的流程体系需要体现出流程的分类分级 03.通用的流程分级方法 04.流程分级的标准 二.企业流程架构设计原则 1.流程架构设计原则 流程框架是流程体…

利用 SoybeanAdmin 实现前后端分离的企业级管理系统

引言 随着前后端分离架构的普及&#xff0c;越来越多的企业级应用开始采用这种方式来开发。前后端分离不仅提升了开发效率&#xff0c;还让前端和后端开发可以并行进行&#xff0c;减少了相互之间的耦合度。SoybeanAdmin 是一款基于 Spring Boot 和 MyBatis-Plus 的后台管理系…

智能风控 数据分析 groupby、apply、reset_index组合拳

目录 groupby——分组 本例 apply——对每个分组应用一个函数 等价用法 reset_index——重置索引 使用前​编辑 注意事项 groupby必须配合聚合函数、 关于agglist 一些groupby试验 1. groupby对象之后。sum&#xff08;一个列名&#xff09; 2. groupby对象…

尚硅谷大数据数仓项目superset db upgrade报错解决(2025.1.23解决)

尚硅谷大数据数仓项目superset db upgrade报错解决&#xff08;2025.1.23解决&#xff09;和 superset安装MySQL报错解决 解决方法&#xff08;2025.1.23解决&#xff09; 0.卸载之前安装好的Superset -- 退出当前环境 conda deactivate-- 卸载Superset conda remove -n sup…

linux-mysql在centos7安装和基础配置

1.安装mysql数据库 1.使用官网安装 1.检查是否存在mysql的分支mariadb [rootlocalhost ~]# rpm -qa |grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 [rootlocalhost ~]# 2.卸载这个分支包 [rootlocalhost ~]# rpm -qa | grep mariadb mariadb-libs-5.5.64-1.el7.x86_64 …

YOLOv5训练自己的数据及rknn部署

YOLOv5训练自己的数据及rknn部署 一、下载源码二、准备自己的数据集2.1 标注图像2.2 数据集结构 三、配置YOLOv5训练3.1 修改配置文件3.2 模型选择 四、训练五、测试六、部署6.1 pt转onnx6.2 onnx转rknn 七、常见错误7.1 训练过程中的错误7.1.1 cuda: out of memory7.1.2 train…

移动端VR处理器和传统显卡的不同

骁龙 XR 系列芯片 更多地依赖 AI 技术 来优化渲染过程&#xff0c;而传统的 GPU 渲染 则倾向于在低画质下运行以减少负载。这种设计是为了在有限的硬件资源下&#xff08;如移动端 XR 设备&#xff09;实现高性能和低功耗的平衡。以下是具体的分析&#xff1a; 1. AI 驱动的渲染…

IoTDB结合Mybatis使用示例(增删查改自定义sql等)

IoTDB时序库是当前越来越流行以及基于其优势各大厂商越来越易接受的国产开源时序数据库&#xff0c;针对IoTDB的内容不做过多介绍&#xff0c;在使用该时序库时&#xff0c;往往有一定入门门槛&#xff0c;不同于关系型数据库或文档型数据库那般方便维护和接入开发&#xff0c;…

Git 小白入门教程

&#x1f3af; 这篇文章详细介绍了版本控制的重要性&#xff0c;特别是通过Git实现的分布式版本控制相对于SVN集中式控制的优势。文章首先解释了版本控制的基本概念&#xff0c;强调了在文档或项目多版本迭代中备份与恢复任意版本的能力。接着&#xff0c;重点阐述了Git的历史背…

搜狐Android开发(安卓)面试题及参考答案

ViewModel 的作用及原理是什么? ViewModel 是 Android 架构组件中的一部分,主要作用是在 MVVM 架构中充当数据与视图之间的桥梁。它负责为视图准备数据,并处理与数据相关的业务逻辑,让视图(Activity、Fragment 等)专注于展示数据和与用户交互。比如在一个新闻应用中,Vie…

Python的泛型(Generic)与协变(Covariant)

今天咱们聊聊Python类型标注中的泛型(Generic),与协变(Covariant)。 不了解类型标注的小伙伴,可以先看一看我的上一篇文章 “Python类型检查” Python 类型检查-CSDN博客 例子 这次我开个宠物商店。看下面代码。 class Animal:passclass Dog(Animal):passclass Cat(A…

.Net Core微服务入门全纪录(四)——Ocelot-API网关(上)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

【二叉树的深搜】二叉树剪枝

文章目录 814. 二叉树剪枝解题思路&#xff1a;深度优先遍历 后序遍历另一种写法 814. 二叉树剪枝 814. 二叉树剪枝 ​ 给你二叉树的根结点 root &#xff0c;此外树的每个结点的值要么是 0 &#xff0c;要么是 1 。 ​ 返回移除了所有不包含 1 的子树的原二叉树。 ​ 节点…

Android SystemUI——自定义状态栏和导航栏(十二)

通过前面的文章内容,我们了解了 Android 系统原生的状态栏 StatusBar 和 车载系统状态栏 CarStatusBar 的启动流程以及视图构建流程,这里我们来简单的看一下自定义状态栏和导航栏视图的实现流程。 一、添加自定义状态栏 修改 CarSystemUI 项目中的 config.xml 配置文件的 co…

CSS实现实现票据效果 mask与切图方式

一、“切图”的局限性 传统的“切图”简单暴力,但往往缺少适应性。 适应性一般有两种,一是尺寸自适应,二是颜色可以自定义。 举个例子,有这样一个优惠券样式 关于这类样式实现技巧,之前在这篇文章中有详细介绍: CSS 实现优惠券的技巧 不过这里略微不一样的地方是,两个…

C语言数组详解:从基础到进阶的全面解析

在C语言中&#xff0c;数组是一种基本的数据结构&#xff0c;用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中&#xff0c;数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中&#xff0c…

Vue2 项目二次封装Axios

引言 在现代前端开发中&#xff0c;HTTP请求管理是构建健壮应用的核心能力之一。Axios作为目前最流行的HTTP客户端库&#xff0c;其灵活性和可扩展性为开发者提供了强大的基础能力。 1. 为什么要二次封装Axios&#xff1f; 1.1 统一项目管理需求 API路径标准化&#xff1a;…

Jmeter 动态参数压力测试时间段预定接口

&#x1f3af; 本文档详细介绍了如何使用Apache JMeter进行压力测试&#xff0c;以评估预定接口在高并发场景下的性能表现。通过创建线程组模拟不同数量的用户并发请求&#xff0c;利用CSV文件动态配置时间段ID和用户token&#xff0c;确保了测试数据的真实性和有效性。文档中还…

Unity常用特性(Attribute)用法

一.UnityEngine命名空间 1.[Header(string)] inspector面板上给显示的字段上加一个描述 通常情况下&#xff0c;用于在 Inspector 窗口中创建字段的逻辑分组 public class AttributeTest : MonoBehaviour {[Header("public_field_num")]public int num; }2.[Tool…