typescript
基本介绍:
究竟什么是ts和js? typescript它是js的超集它是Microsoft公司创造的解决了javascript的小毛病,虽然说js写起来很爽很带劲,不用想太多直接就是一把梭哈,但是ts的出现确实是解决了js的不足 如:缺少类型检查 “1”+2 =3 这行代码在js里面会被执行称为3,自动转换,还有种种问题就不一一描述了,Ts的出现解决了很多不足:静态类型检查,面向对象编程特性,代码自动补全和重构支持,特别是大型项目的可维护型.
学习好处:
很多库和框架都有很好的配合ts, 以后学习ArkTS 语言也是很有帮助的下面是鸿蒙官方的介绍:
ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript(简称TS)基本语法风格的基础上,进一步通过规范强化静态检查和分析,使得在程序运行之前的开发期能检测更多错误,提升代码健壮性,并实现更好的运行性能。同时,提供了声明式UI范式、状态管理支持等相应的能力,让开发者可以以更简洁、更自然的方式开发高性能应用。
- 提高代码质量
- 提高开发效率
- 增强可维护性
- 更好的重构支持
- 更好的团队协作
- 跨平台支持
- 更好的工具支持
- 更好的可读性
基本语法
let a = 1;
a = 10;
// a = '10'; 类型报错,因为之前我们声明了a的类型是number
console.log(a);
//两种方法一致 ⬆️⬇️
let x: string;
x = 'hallo';
x = 1; //报错
const fn = (a: number, b: number): number => {
//声明函数(a:定义类型, b:定义类型,) 返回值类型:number
return a + b;
}
console.log(fn(1,2));
类型
类型 | 例子 | 描述 |
---|---|---|
number | 1,-33.2.5 | 任意数字 |
string | 'hi", “hi”, hi | 任意字符串 |
boolean | true, false | 布尔值true或false |
字面量 | 其本身 | 限制变量的值就是该字面量的值 I |
any | * | 任意类型 |
unknown | * | 类型安全的any |
void | 空值(undefined) | 没有值(或undefined) |
never | 没有值 | 不能是任何值 |
object | {name:孙悟空} | 任意的JS对象 |
array | [1,2,3] | 任意IS数组 |
tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
enum | enum{A, B} | 枚举,TS中新增类型 |
字面量
let a:10|false; //可以用| 或 来链接多个类型(联合类型)
a = 10;
a = false; //error 不能讲11赋值给a
类似于const 限制它的值为
any
任意类型,随意赋值, 设置了any可以相当于ts关闭了类型检测 相当于写js 没有任何区别
object
// 定义类型,必填的 name、age、sex,其中 sex 只能选择 'man' 或 'woman'
let data: { name: string, age: number, sex: 'man' | 'woman' } = {
name: '张三',
age: 18,
sex: 'man'
}
console.log(data);
// 定义类型,必填的 name、age,sex 是可选的
let user: { name: string, age: number, sex?: string } = {
name: '张三',
age: 18
}
// 定义类型,name 是必填的 string 类型,其他属性可以是任意类型
let zoon: { name: string, [zoonSpecies: string]: any } = {
name: '小花',
species: 'panda',
age: 18
}
Array
String[] 字符串数组
let arr: string[]
arr = ['a', 'b', 'c']
let arr2: Array<number> = [1, 2, 3]
console.log(arr2,arr);
元祖
let data: [number, string] = [1, '2'];
console.log(data);
enum 枚举
// 定义一个枚举类型 Sex,其中 man 为 1,woman 为 0
enum Sex {
man = 1,
woman = 0
}
// 定义一个对象类型 user,包含 name 和 gender 属性
// gender 属性的类型是 Sex 枚举类型
let user: { name: string, gender: Sex } = {
name: '张三',
gender: 1 // 将 gender 设置为 1,对应 Sex.man
}
// 打印出 user.gender 是否等于 Sex.woman(false)
console.log(user.gender === Sex.woman);
unkown
中间转换
function processInput(input: unknown): void {
if (typeof input === 'string') {
console.log(`You entered: ${input.toUpperCase()}`);
} else if (typeof input === 'number') {
console.log(`The square of ${input} is ${input * input}`);
} else {
console.log('Invalid input type');
}
}
// 使用 unknown 类型
processInput('hello');
processInput(42);
processInput(true); // 输出 "Invalid input type"
编译选项
创建一个 tsconfig.json文件
tsconfig.json是ts编译器的配置文件,ts編译器可以根据它的信息来对代码进行编译
"include"用来指定哪些ts文件需要被编译
路径:** 表示任意日录
* 表示任意文件
"excLude"不需要被编译的文件日录
ЖИІ: ["node_modules", "bower_components", "jspm_packages"]
files 指定被编译的列表,自由需要编译文件少的时候才会用到
•例子:
"files": [
"core.ts",
"sys.ts"
"types.ts",
"scanner.ts",
"parser.ts"
"utilities.ts",
"binder.ts"
"checker.ts",
"tsc.ts"
]
• 列表中的文件都会被TS编译器所编译
• compilerOptions
• 编译选项是配置文件中非常重要也比较复杂的配置选项
• 在compilerOptions中包含多个子选项,用来完成对编译的配置
•项目选卖」
target
• 设置tS代码编译的目标版本
• 可选值:
• 示例:
• ES3(默认)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
"compilerOptions" : {
"target": "ES6"
• 如上设置,我们所编写的ts代码将会被编译为ES6版本的js代码
• lib
• 指定代码运行时所包含的库(宿主环境)
• 可选值:
• ES5, ES6/ES2015, ES7/ES2016, ES2017, ES2018, ES2019, ES2020, ESNext. DOM,
WebWorker, ScriptHost .....、
"outDir":'./dist' //用来存储编译后的存储的目录
//将代码合并为一个js
"outFile":""
//是否对js文件进行编译,默认是false
"allowjs":true;
//是否检查js代码是否合法规范 默认是false
"chackJS":true
{
"include": [ //指定哪些文件需要被ts编译
"src/*"
]
}
类 (class)
要面向对象,操作对象,首先便要拥有对象,那么下一个问题就是如何创建对象。要创建对象,必须要先定义类,所谓的类可以理解为对象的模型,程序中可以根据类创建指定类型的对象,举例来说:可以通过Person类来创建人的对象,通过Dog类创建狗的对象,通过Car类来创建汽车的对象,不同的类可以用来创建不同的对象。
class userData {
name = "panda";
age = 18;
sayHallo() {
console.log("hello" + this.name + "my age is" + this.age);
}
}
const myuser = new userData();
console.log(myuser.sayHallo());
constructor
构造函数
// 定义一个名为 Dog 的类
class Dog {
// 声明 name 和 age 两个属性,类型分别为 string 和 number
name: string;
age: number;
// 构造函数,用于初始化 name 和 age 属性
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 定义一个名为 bark 的方法
bark() {
// 在控制台打印出 "this is " 加上 name 属性的值
console.log('this is ' + this.name);
}
}
// 创建一个名为 dog 的 Dog 类实例,初始化 name 为 '小黑',age 为 2
const dog = new Dog('小黑', 2);
// 创建另一个名为 dog2 的 Dog 类实例,初始化 name 为 '小白',age 为 2.3
const dog2 = new Dog('小白', 2.3);
// 调用 dog 实例的 bark 方法,输出 "this is 小黑"
dog.bark();
extends(继承)
OCP原则!!!
class father {
//定义类型
name: string;
age: number;
constructor(name: string, age: number) {
//构造函数 通过new 创建实例的时候会调用
this.name = name;
this.age = age;
}
sayHallo() {
console.log('zoon在say!!!');
}
}
class BigDog extends father{
//利用extends继承过来我们的父亲元素的参数
sayHallo() {
//如果和父亲元素相同的方法,子方法会覆盖父方法
console.log(this.name+'在say!!!');
}
}
class Smallcat extends father{
sayHallo() {
// console.log(this.name+'在say!!!');
super.sayHallo(); // 调用父类的方法
}
}
const dog = new BigDog('旺财', 2); //创造实例
const cat= new Smallcat('小花', 1);
dog.sayHallo();// 调用方法
cat.sayHallo();
super
super就是引用父类的实例方法
class father {
//定义类型
name: string;
age: number;
constructor(name: string, age: number) {
//构造函数 通过new 创建实例的时候会调用
this.name = name;
this.age = age;
}
sayHallo() {
console.log('zoon在say!!!');
}
}
class BigDog extends father{
//利用extends继承过来我们的父亲元素的参数
sayHallo() {
//如果和父亲元素相同的方法,子方法会覆盖父方法
console.log(this.name+'在say!!!');
}
}
class Smallcat extends father{
count: number;
constructor(name:string,age:number,count: number) {
super(name,age); //添加新的方法需要先使用super
this.count=count;
}
sayHallo() {
// console.log(this.name+'在say!!!');
super.sayHallo(); // 调用父类的方法
}
myCat() {
console.log('mayCat have '+this.count+' cat');
}
}
const dog = new BigDog('旺财', 2); //创造实例
const cat= new Smallcat('小花', 1,5);
dog.sayHallo();// 调用方法
cat.sayHallo();
cat.myCat();
## 抽象类 abstract
class father {
//定义类型
name: string;
age: number;
constructor(name: string, age: number) {
//构造函数 通过new 创建实例的时候会调用
this.name = name;
this.age = age;
}
sayHallo() {
console.log('zoon在say!!!');
}
}
cosnt fromer=new father("小明",18);
当我们不希望公共的组件被定义实例的时候,我们可以使用抽象类来解决这样的问题
interface和type
它们两者大同小异:
- 语法差异:
type
使用等号=
来定义类型别名。interface
直接声明一个接口类型。
- 扩展性差异:
type
可以使用联合类型 (|
)、交叉类型 (&
) 等高级类型语法来定义更复杂的类型。interface
可以通过extends
关键字来扩展和组合现有的接口类型。
- 合并差异:
- 对于
interface
,TypeScript 会自动合并具有相同名称的接口声明,形成一个单一的接口类型。 - 对于
type
,TypeScript 不会自动合并同名的类型别名声明,它们是相互独立的。
- 对于
- 灵活性差异:
type
可以用于定义任何类型,包括原始类型、联合类型、元组类型等。interface
主要用于定义对象类型,不太适合定义其他类型。
综合来看,type
和 interface
的主要区别在于:
type
更灵活,可以定义各种复杂类型,而interface
主要用于定义对象类型。interface
可以通过extends
进行继承和扩展,而type
需要使用交叉类型 (&
) 来实现类似的效果。interface
可以合并同名声明,type
则不会自动合并。
在实际开发中,选择使用 type
还是 interface
主要取决于你的需求和个人偏好。通常来说,如果你需要定义对象类型,使用 interface
会更简洁和易读;如果你需要定义更复杂的类型,使用 type
会更加灵活。
type require = {
//type是用来定义多个类型的
name: string,
age: number
}
interface requireS {
//interface用来定义一个类型
name: string,
age: number
}
使用起来都差不多 type 使用起来来和string number 等差不错
const xiaoming: require = {
name: '小明',
age: 18
}
interface 定义后(接口),需要通过implements来配合使用
class dog implements requireS {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
public和private protected
公共和私有的
默认的值都是 public
private 私有的
protected 受保护的
如果状态值 为私有的状态值ts这边是显示报错了但是js还是编译了,这是因为我们ts运行后会编译成js,如果不希望带着错误去编译,需要找到tsconfig.json 把 “noEmitonError” :设置为true
设置完毕如果ts有错误就不会继续编译成js
get set
es6自带的 方法实用ruent需要的参数就行了
泛型
TypeScript 的泛型(Generics)是一种功能强大的特性,它允许编写可重用的、类型安全的代码。泛型使得代码可以应对不同类型的数据,同时保持类型安全性。
泛型的基本用法如下:
- 定义泛型函数:
function identity<T>(arg: T): T {
return arg;
}
在这个例子中,<T>
是一个类型参数,它可以代表任何类型。当调用 identity
函数时,TypeScript 会自动推断出 T
的类型。
- 使用泛型函数:
let output1 = identity<string>("myString"); // 类型为 string
let output2 = identity(42); // 类型为 number
- 定义泛型接口:
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
在这个例子中,我们定义了一个泛型接口 GenericIdentityFn
,它描述了一个函数类型,该函数接受一个类型为 T
的参数,并返回一个类型也为 T
的值。
- 定义泛型类:
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
,它可以处理任何类型的数值。
泛型的主要优点包括:
- 代码复用性:泛型允许编写一次代码,就可以处理多种类型的数据。
- 类型安全性:泛型可以确保代码在编译时就能发现类型错误。
- 灵活性:泛型可以根据具体情况选择不同的类型参数,提高代码的灵活性。
总之,TypeScript 的泛型是一个非常强大和实用的特性,它可以帮助开发者编写出更加通用、类型安全的代码。