2024-08-22

TypeScript 是 JavaScript 的一个超集,并且添加了一些静态类型的特性。它可以编译成纯 JavaScript,以供现代的网络浏览器或者任何环境下运行。

安装TypeScript

首先,你需要在你的电脑上安装TypeScript。你可以通过npm(Node.js的包管理器)来安装它。




npm install -g typescript

创建TypeScript文件

创建一个.ts扩展名的文件,例如hello.ts




function greet(name: string) {
    return `Hello, ${name}!`;
}
 
console.log(greet('World'));

编译TypeScript

要将TypeScript编译成JavaScript,你可以使用tsc命令。




tsc hello.ts

这将生成一个名为hello.js的文件,包含相应的JavaScript代码。

运行JavaScript代码

现在你可以运行生成的JavaScript文件。




node hello.js

你应该看到输出Hello, World!

使用tsconfig.json

tsconfig.json文件用于配置TypeScript项目。它应该位于项目的根目录中。




{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "outDir": "./dist",
        "sourceMap": true
    },
    "include": [
        "./src/**/*"
    ]
}

使用这个配置文件,你可以一次性编译整个项目。




tsc

这将编译src文件夹中的所有TypeScript文件,并将生成的JavaScript文件放在dist文件夹中。

2024-08-22



{
  "name": "uni-app-typescript-example",
  "version": "1.0.0",
  "scripts": {
    "dev": "cross-env UNI_PLATFORM=h5 vue-cli-service uni-build --watch",
    "build": "cross-env UNI_PLATFORM=h5 vue-cli-service uni-build"
  },
  "dependencies": {
    "vue": "^2.6.11",
    "uni-simple-router": "^2.4.3",
    "uni-simple-store": "^2.4.3",
    "@dcloudio/types": "^2.0.5",
    "@types/node": "^14.14.25",
    "typescript": "^4.0.5"
  },
  "devDependencies": {
    "@vue/cli-service": "^4.5.15",
    "@vue/cli-plugin-typescript": "^4.5.15",
    "cross-env": "^7.0.3"
  }
}

这个配置文件定义了一个使用uni-app和TypeScript的项目。它指定了项目的名称和版本,并定义了用于开发和构建的脚本。同时,它列出了所需的npm依赖项,包括uni-app的核心库、uni-simple-router和uni-simple-store,以及TypeScript的类型定义。这为开发者提供了一个基本的配置框架,可以根据具体需求进行扩展和定制。

2024-08-22

在TypeScript中,接口(Interface)是一种结构化的数据类型系统,它可以用来定义对象的形状(即属性和方法)。接口是TypeScript的核心部分,它能够确保对象按预定的方式工作。

以下是一个简单的TypeScript接口的示例:




interface Person {
    name: string;
    age: number;
}
 
function introduce(person: Person) {
    console.log(`My name is ${person.name} and I am ${person.age} years old.`);
}
 
const person1: Person = {
    name: 'Alice',
    age: 25
};
 
introduce(person1);

在这个例子中,我们定义了一个Person接口,它有两个属性:nameage。然后我们定义了一个introduce函数,它接受一个Person类型的参数。最后,我们创建了一个person1对象,它符合Person接口的形状,并调用了introduce函数。

接口还可以包含可选属性、只读属性、方法、类等,以及它们的混合体。例如,你可以这样定义一个带有可选属性和方法的接口:




interface Person {
    name: string;
    age: number;
    email?: string;
    introduce(): void;
}
 
const person2: Person = {
    name: 'Bob',
    age: 30,
    introduce() {
        console.log(`Hello, my name is ${this.name}.`);
    }
};
 
person2.introduce();

在这个例子中,email是一个可选属性,introduce方法是必须由实现接口的类或对象提供的。

2024-08-22

以下是一个使用TypeScript实现的BASE64编码和解码的简单例子:




// 定义一个BASE64编码的映射表
const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
// BASE64编码函数
function encode(input: string): string {
  let output = "";
  let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  let i = 0;
 
  input = utf8_encode(input);
 
  while (i < input.length) {
    chr1 = input.charCodeAt(i++);
    chr2 = input.charCodeAt(i++);
    chr3 = input.charCodeAt(i++);
 
    enc1 = chr1 >> 2;
    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
    enc4 = chr3 & 63;
 
    if (isNaN(chr2)) {
      enc3 = enc4 = 64;
    } else if (isNaN(chr3)) {
      enc4 = 64;
    }
 
    output +=
      keyStr.charAt(enc1) +
      keyStr.charAt(enc2) +
      keyStr.charAt(enc3) +
      keyStr.charAt(enc4);
  }
 
  return output;
}
 
// BASE64解码函数
function decode(input: string): string {
  let output = "";
  let chr1, chr2, chr3;
  let enc1, enc2, enc3, enc4;
  let i = 0;
 
  // 移除所有非BASE64字符
  input = input.replace(/[^A-Za-z0-9+\/=]/g, "");
 
  while (i < input.length) {
    enc1 = keyStr.indexOf(input.charAt(i++));
    enc2 = keyStr.indexOf(input.charAt(i++));
    enc3 = keyStr.indexOf(input.charAt(i++));
    enc4 = keyStr.indexOf(input.charAt(i++));
 
    chr1 = (enc1 << 2) | (enc2 >> 4);
    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
    chr3 = ((enc3 & 3) << 6) | enc4;
 
    output += String.fromCharCode(chr1);
 
    if (enc3 !== 64) {
      output += String.fromCharCode(chr2);
    }
    if (enc4 !== 64) {
      output += String.fromCharCode(chr3);
    }
  }
 
  output = utf8_decode(output);
 
  return output;
}
 
// UTF-8编码函数(用于内部处理)
function utf8_encode(string: string): string {
  string = string.replace(/\r\n/g, "\n");
  let utfText = "";
 
  for (let n = 0; n < string.length; n++) {
    const c = string.charCodeAt(n);
 
    if (c < 128) {
      utfText += String.fromCharCode(c);
    } else if (c > 127 && c < 2048) {
      utfText += String.fromCharCode((c >> 6) | 192);
      utfText += String.fromCharCode((c & 63) | 128);
    } else {
      utfText += String.fromCharCode((c >> 12) | 224);
      utfText += String.fromCharCode(((c >> 6) & 63) | 128);
      utfText += String.fromCharCode((c & 63) | 128);
    }
  }
 
 
2024-08-22

在TypeScript中,常见的操作符包括:

  1. 算术操作符:+, -, *, /, %
  2. 一元操作符:+, -, ~, --, ++
  3. 关系操作符:>, <, >=, <=
  4. 相等操作符:==, !=, ===, !==
  5. 条件操作符(三元操作符):? :
  6. 赋值操作符:=, +=, -=, *=, /=, %=, **=
  7. 位操作符:&, |, ^, <<, >>, >>>
  8. 逻辑操作符:&&, ||, !
  9. 逗号操作符:,
  10. 类型操作符:typeof, keyof, in, instanceof

以下是一些示例代码:




let a = 10;
let b = 5;
 
// 算术操作符
let sum = a + b; // 加法
let diff = a - b; // 减法
let prod = a * b; // 乘法
let quot = a / b; // 除法
let rem = a % b; // 取模
 
// 一元操作符
let neg = -a; // 负号
let not = ~a; // 按位取反
let preInc = ++a; // 前递增
let postInc = a++; // 后递增
 
// 关系操作符
let greater = a > b; // 大于
let less = a < b; // 小于
let greaterEq = a >= b; // 大于等于
let lessEq = a <= b; // 小于等于
 
// 相等操作符
let eq = a == b; // 等于
let neq = a != b; // 不等于
let seq = a === b; // 严格等于
let sneq = a !== b; // 严格不等于
 
// 条件操作符(三元操作符)
let condition = a > b ? "a is greater than b" : "a is not greater than b";
 
// 赋值操作符
let assign = a; // 简单赋值
let addAssign = a += b; // 加法赋值
let subAssign = a -= b; // 减法赋值
let mulAssign = a *= b; // 乘法赋值
let divAssign = a /= b; // 除法赋值
let modAssign = a %= b; // 取模赋值
 
// 位操作符
let bitAnd = a & b; // 按位与
let bitOr = a | b; // 按位或
let bitXor = a ^ b; // 按位异或
let bitShiftLeft = a << 2; // 左移
let bitShiftRight = a >> 2; // 有符号右移
let bitShiftRightZerofill = a >>> 2; // 无符号右移
 
// 逻辑操作符
let logicalAnd = a > 0 && b > 0; // 逻辑与
let logicalOr = a > 0 || b > 0; // 逻辑或
let logicalNot = !(a > 0); // 逻辑非
 
// 逗号操作符
let comma = (a++, b++, a + b); // 用于连接多个表达式
 
// 类型操作符
let aType = typeof a; // 获取变量的类型
let key = "toString" as keyof typeof a; // 获取对象的键类型
let hasKey = "toString" in aType; // 检查对象是否具有某个键
let checkInstance = a instanceof Number; // 检查对象是否是某个构造函数的实例

这些操作符在TypeScript中都是受支持的,并且每个操作符都有其特定的行为和结果。

2024-08-22

在TypeScript中,我们可以为JavaScript添加静态类型检查,以提高代码的可维护性和可预测性。以下是一些TypeScript的关键概念和语法:

  1. 类型注解:为变量指定类型。



let count: number = 10;
  1. 接口:定义复杂类型。



interface Person {
  name: string;
  age: number;
}
 
let tom: Person = { name: "Tom", age: 25 };
  1. 类:定义对象的类型。



class Person {
  name: string;
  age: number;
 
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
 
let tom: Person = new Person("Tom", 25);
  1. 泛型:允许定义可复用的组件,该组件可以支持多种类型。



function identity<T>(arg: T): T {
  return arg;
}
 
let output = identity<string>("Hello World");
  1. 类型别名:为类型定义别名。



type Person = {
  name: string;
  age: number;
};
 
let tom: Person = { name: "Tom", age: 25 };
  1. 类型断言:告诉编译器你比它更了解代码。



let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;
  1. 异步函数:处理异步代码。



async function fetchData(): Promise<string> {
  let response = await fetch("https://api.example.com/data");
  return await response.text();
}
  1. 装饰器:用于修改类的行为。



function logClass(target) {
  target.isLogged = true;
}
 
@logClass
class MyClass {}
 
console.log(MyClass.isLogged); // 输出:true

以上是TypeScript的一些基本概念和语法,实际项目中可能还会涉及更多高级特性,如装饰器、泛型、元组、枚举等。

2024-08-22



// 定义一个简单的TypeScript接口
interface Person {
  name: string;
  age: number;
}
 
// 使用接口创建一个函数,接收一个符合Person接口的对象
function greetPerson(person: Person) {
  console.log("Hello, " + person.name + ". Next year, you'll be " + (person.age + 1));
}
 
// 创建一个符合Person接口的对象
let person1: Person = {
  name: "Alice",
  age: 30
};
 
// 调用函数并传入该对象
greetPerson(person1);

这段代码定义了一个Person接口,并创建了一个greetPerson函数,该函数接受一个符合Person接口的对象作为参数。然后,代码中创建了一个person1对象,该对象符合Person接口的定义,并调用greetPerson函数输出问候语。这个例子展示了如何在TypeScript中定义接口和使用接口来增强代码的可读性和可维护性。

2024-08-22

在TypeScript中,你可以使用可选属性来表示某些字段在对象中可以不存在。可选方法则表示在类的实例中,某些方法可以不被实现。

下面是一个使用可选属性和可选方法的例子:




// 定义一个带有可选属性和可选方法的类型
interface Person {
  name: string;
  age?: number;
  greet?(): void;
}
 
// 实现这个接口的一个具体对象
const person: Person = {
  name: "Alice",
  greet() {
    console.log(`Hello, my name is ${this.name}`);
  },
};
 
// 可以不提供age和greet方法
const anotherPerson: Person = {
  name: "Bob",
};

在这个例子中,Person 接口有两个可选属性:agegreetanotherPerson 对象可以不包含这些可选属性和方法。

2024-08-22

在TypeScript中,你可以使用以下方法来找出数组中的最小和最大的n个元素:

  1. 使用sort()方法对数组进行排序。
  2. 使用slice()方法获取前n个元素。

以下是实现这一功能的示例代码:




function findMinMaxN<T>(arr: T[], n: number, compareFn?: (a: T, b: T) => number): T[] {
    if (n <= 0 || arr.length <= n) {
        return [];
    }
 
    const sorted = arr.sort(compareFn).slice(0, n);
    return sorted;
}
 
// 示例
const numbers = [4, 2, 8, 6, 3, 5, 1, 7];
const minMax2 = findMinMaxN(numbers, 2); // 找到最小的2个元素
console.log(minMax2); // 输出 [1, 2]
 
const minMax4 = findMinMaxN(numbers, 4); // 找到最小的4个元素
console.log(minMax4); // 输出 [1, 2, 3, 4]

在这个例子中,findMinMaxN函数接受一个泛型数组arr,一个表示需要返回的元素个数n,以及一个可选的比较函数compareFn。如果n大于数组长度,函数将返回空数组。否则,它将使用sort()方法对数组进行排序(可以通过compareFn自定义排序规则),然后使用slice()方法返回前n个元素。

请注意,如果你需要同时找到最大和最小的n个元素,你可能需要定义一个更复杂的比较函数,或者两次调用findMinMaxN函数,一次以升序排序,一次以降序排序。

2024-08-22

在 TypeScript 中,可以使用命名空间来组织代码,类似于其他语言中的 Static 类。以下是一些使用 TypeScript 命名空间的方法:

方法一:简单的命名空间




namespace MyNamespace {
    export let myVariable: string = "Hello, world!";
 
    export function myFunction() {
        console.log(myVariable);
    }
}
 
MyNamespace.myFunction();  // Outputs: Hello, world!

在这个例子中,我们创建了一个名为 MyNamespace 的命名空间,并在其中定义了一个变量 myVariable 和一个函数 myFunction。要访问这些成员,我们需要使用 MyNamespace 前缀。

方法二:嵌套命名空间




namespace MyNamespace {
    export let myVariable: string = "Hello, world!";
 
    export function myFunction() {
        console.log(myVariable);
    }
 
    export namespace NestedNamespace {
        export let myNestedVariable: string = "Hello, nested world!";
 
        export function myNestedFunction() {
            console.log(myNestedVariable);
        }
    }
}
 
MyNamespace.NestedNamespace.myNestedFunction();  // Outputs: Hello, nested world!

在这个例子中,我们创建了一个嵌套在 MyNamespace 内的 NestedNamespace。要访问嵌套命名空间的成员,我们需要使用 MyNamespaceNestedNamespace 前缀。

方法三:合并命名空间




namespace MyNamespace {
    export let myVariable: string = "Hello, world!";
 
    export function myFunction() {
        console.log(myVariable);
    }
}
 
namespace MyNamespace {
    export let myNewVariable: string = "Hello, new world!";
 
    export function myNewFunction() {
        console.log(myNewVariable);
    }
}
 
MyNamespace.myNewFunction();  // Outputs: Hello, new world!

在这个例子中,我们定义了两个具有相同名称的命名空间。TypeScript 会合并这两个命名空间,因此我们可以在任何一个命名空间中定义成员,而不会产生冲突。

方法四:使用模块来代替命名空间




module MyModule {
    export let myVariable: string = "Hello, world!";
 
    export function myFunction() {
        console.log(myVariable);
    }
}
 
MyModule.myFunction();  // Outputs: Hello, world!

在 TypeScript 2.0 及以后的版本中,模块成为了首选的代码组织方式,它与命名空间在语义上非常相似。模块可以嵌套定义,也可以合并。

以上就是在 TypeScript 中使用命名空间的一些方法。