2024-08-19

在TypeScript中,接口(Interface)是一种结构化的数据类型系统,它能够明确地定义对象的形状。接口可以被用来为这些对象定义可选或必需的属性以及它们的类型。

下面是一个简单的TypeScript接口的例子:




interface Person {
  name: string;
  age?: number; // 可选属性
}
 
function greet(person: Person) {
  return `Hello, my name is ${person.name} and I am ${person.age} years old.`;
}
 
let person1: Person = { name: "Alice" };
let person2: Person = { name: "Bob", age: 30 };
 
console.log(greet(person1)); // Hello, my name is Alice and I am undefined years old.
console.log(greet(person2)); // Hello, my name is Bob and I am 30 years old.

在这个例子中,我们定义了一个Person接口,它要求有一个name属性,类型为string。我们还定义了一个可选的age属性,类型为number。然后我们定义了一个greet函数,它接受一个Person类型的参数,并返回一个包含个人信息的问候字符串。

最后,我们创建了两个Person对象,一个包含name,另一个包含nameage。这两个对象都可以被greet函数接受,因为它们都符合Person接口的结构。

2024-08-19



// 定义一个函数,输出 "Hello, World!"
function sayHello(): void {
    console.log("Hello, World!");
}
 
// 调用函数
sayHello();

这段代码定义了一个简单的函数sayHello,它没有返回值(使用了void类型),并在函数内部使用了console.log来输出"Hello, World!"。然后调用了这个函数,以便执行并展示结果。这是学习TypeScript的一个基本例子,展示了如何定义一个简单的函数并运行它。

2024-08-19

在TypeScript中,我们可以使用抽象类来定义一种模板,这个模板包含了一些抽象的方法和属性,继承了抽象类的子类需要实现这些抽象方法和属性。抽象类不能直接实例化,只能用于继承。

下面是一个使用抽象类的例子:




abstract class Animal {
    // 抽象属性,子类必须实现
    abstract name: string;
 
    // 抽象方法,子类必须实现
    abstract makeSound(): void;
 
    // 具体方法
    move(): void {
        console.log('Animals can move.');
    }
}
 
class Dog extends Animal {
    name: string;
 
    constructor(name: string) {
        super();
        this.name = name;
    }
 
    makeSound(): void {
        console.log('Woof! My name is ' + this.name);
    }
}
 
class Cat extends Animal {
    name: string;
 
    constructor(name: string) {
        super();
        this.name = name;
    }
 
    makeSound(): void {
        console.log('Meow! My name is ' + this.name);
    }
}
 
let myDog = new Dog('Rex');
let myCat = new Cat('Whiskers');
 
myDog.makeSound(); // Output: Woof! My name is Rex
myCat.makeSound(); // Output: Meow! My name is Whiskers

在这个例子中,Animal 是一个抽象类,它定义了 name 抽象属性和 makeSound 抽象方法。DogCat 类继承了 Animal 类,并且实现了所有抽象的属性和方法。这样,我们就可以在 DogCat 类中定义具体的行为,而不用在 Animal 类中重复实现相同的逻辑。

2024-08-19

以下是一个简化的TypeScript代码示例,用于实现贪吃蛇游戏中的蛇部分。这个示例只包含了蛇的基本属性和移动功能。




class Snake {
    body: number[][];  // 蛇的身体,使用二维数组表示位置
    direction: 'up' | 'down' | 'left' | 'right'; // 蛇的移动方向
 
    constructor() {
        this.body = [[2, 2], [1, 2], [0, 2]]; // 初始蛇的位置
        this.direction = 'right'; // 初始方向
    }
 
    move(food: number[]): void {
        const nextHead = this.getNextHead();
        if (this.isEating(food, nextHead)) {
            this.body.push(nextHead); // 吃到食物,蛇长大
        } else {
            this.body.push(nextHead); // 没吃食物,蛇前进
            this.body.shift(); // 蛇尾部移除
        }
    }
 
    getNextHead(): number[] {
        const [x, y] = this.body[this.body.length - 1];
        switch (this.direction) {
            case 'up': return [x - 1, y];
            case 'down': return [x + 1, y];
            case 'left': return [x, y - 1];
            case 'right': return [x, y + 1];
        }
    }
 
    isEating(food: number[], nextHead: number[]): boolean {
        return nextHead[0] === food[0] && nextHead[1] === food[1];
    }
 
    changeDirection(newDirection: 'up' | 'down' | 'left' | 'right'): void {
        const oppositeDirection = { 'up': 'down', 'down': 'up', 'left': 'right', 'right': 'left' };
        if (newDirection !== oppositeDirection[this.direction]) {
            this.direction = newDirection;
        }
    }
}
 
// 使用示例
const snake = new Snake();
const food = [1, 1]; // 假设食物在坐标(1, 1)
 
// 玩家按键,改变蛇的移动方向
snake.changeDirection('left');
 
// 游戏循环中调用snake.move(food)更新蛇的位置

这个代码实现了基本的贪吃蛇游戏中蛇的部分。它包括蛇的移动逻辑,包括蛇吃食物时的增长和没吃食物时的移动。这个示例没有实现游戏的其他部分,比如与屏幕边界的碰撞检测、蛇吃蛇本身的检测等。实际的游戏可能需要更复杂的逻辑来处理这些情况。

2024-08-19

在TypeScript或JavaScript中,我们可以使用正则表达式来匹配除了预期之外的字符。这可以通过一个负向字符集来实现。

解法1:使用[^...]定义一个否定的字符集。




let str = "abc123";
let regExp = /[^0-9]/; // 匹配除了数字以外的任意字符
console.log(str.match(regExp)); // 输出:"abc"

解法2:使用[^...]定义一个否定的字符集,并使用量词?来使匹配为非贪婪匹配。




let str = "abc123";
let regExp = /[^0-9]+?/; // 匹配除了数字以外的字符,量词?使其为非贪婪匹配
console.log(str.match(regExp)); // 输出:undefined

解法3:使用(?!...)负向前瞻断言。




let str = "abc123";
let regExp = /.*(?!123)/; // 匹配不以"123"结尾的所有字符
console.log(str.match(regExp)); // 输出:"abc"

解法4:使用(?!...)负向前瞻断言,并使用量词?来使匹配为非贪婪匹配。




let str = "abc123";
let regExp = /.*?(?!123)/; // 匹配不以"123"结尾的字符,量词?使其为非贪婪匹配
console.log(str.match(regExp)); // 输出:undefined

以上就是在TypeScript或JavaScript中使用正则表达式来匹配除了预期之外的字符的几种方法。

2024-08-19

在Vue 3和TypeScript中使用Ant Design Vue 3创建一个Modal表单,你可以使用Modal组件的form属性来简化表单的创建过程。以下是一个简单的例子:




<template>
  <a-button type="primary" @click="showModal">
    打开表单Modal
  </a-button>
  <a-modal
    v-model:visible="isModalVisible"
    title="表单Modal"
    :width="600"
    :bodyStyle="{ padding: '24px 24px 0' }"
    destroyOnClose
    :maskClosable="false"
    :modalRender="modalRender"
  />
</template>
 
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Modal, Form, Input, Button } from 'ant-design-vue';
 
export default defineComponent({
  setup() {
    const isModalVisible = ref<boolean>(false);
 
    const showModal = () => {
      isModalVisible.value = true;
    };
 
    const modalRender = (formProps: any) => {
      return (
        <Form {...formProps}>
          <Form.Item label="名称" name="name">
            <Input />
          </Form.Item>
          <Form.Item label="描述" name="description">
            <Input.TextArea />
          </Form.Item>
          <Form.Item wrapperCol={{ offset: 4, span: 16 }}>
            <Button type="primary" htmlType="submit">
              提交
            </Button>
            <Button type="link" onClick={formProps.onReset}>
              重置
            </Button>
          </Form.Item>
        </Form>
      );
    };
 
    return {
      isModalVisible,
      showModal,
      modalRender,
    };
  },
});
</script>

在这个例子中,我们创建了一个Modal窗口,并通过modalRender属性定义了一个渲染函数,该函数使用Form组件来渲染一个表单。当用户点击打开表单的按钮时,showModal函数被触发,显示Modal窗口。用户填写表单并提交后,Modal窗口将关闭。

2024-08-19

在Vite + Vue3 + TypeScript项目中配置路径别名,可以使用tsconfig.json文件来实现。

打开项目根目录下的tsconfig.json文件,然后在compilerOptions中添加baseUrlpaths配置:




{
  "compilerOptions": {
    "baseUrl": ".", // 这里设置基础路径为项目根目录
    "paths": {
      "@/*": ["./*"] // 定义一个别名@指向根目录
    }
    // ...其他配置
  },
  // ...其他配置
}

这样配置后,在代码中就可以使用@作为别名来引用根目录下的文件,例如:




// 引用src目录下的utils.ts文件
import Utils from '@/utils.ts';

请注意,Vite 使用其自己的别名解析逻辑,通常不需要在tsconfig.json中配置paths。但是,如果你需要在TypeScript中使用别名,上述配置仍然适用。

2024-08-19



// 定义一个简单的用户类型
interface User {
  id: number;
  name: string;
  email?: string; // 可选属性
}
 
// 定义一个函数,接受User类型的参数
function greet(user: User) {
  return `Hello, ${user.name}!`;
}
 
// 使用
let user: User = { id: 1, name: "Alice" };
console.log(greet(user)); // 输出: Hello, Alice!

这段代码定义了一个简单的用户接口User,并且定义了一个接受User类型参数的greet函数。然后,我们创建了一个User类型的实例,并调用了greet函数。这个例子展示了TypeScript中如何定义和使用类型,以及如何在实际代码中应用它们。

2024-08-19



// 定义一个用户接口
interface User {
  id: number;
  name: string;
  email: string;
}
 
// 定义一个函数,接受User类型的参数
function greet(user: User) {
  return `Hello, ${user.name}!`;
}
 
// 使用
let user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com"
};
 
console.log(greet(user)); // 输出: Hello, Alice!

这段代码展示了如何在TypeScript中定义一个接口和一个使用该接口作为参数的函数。然后,我们创建了一个符合该接口的对象,并将其传递给函数,最后打印出了问候语。这是TypeScript的一个基本示例,它演示了类型检查和接口的用法。

2024-08-19

在TypeScript中,面向对象编程可以通过类和接口来实现。以下是一个简单的例子,展示了如何定义一个类和使用它的基本方法。




// 定义一个接口,描述了具有 'name' 属性的对象
interface Named {
  name: string;
}
 
// 定义一个类 'Person',它实现了 'Named' 接口
class Person implements Named {
  name: string;
  
  // 构造函数用于初始化 'name' 属性
  constructor(name: string) {
    this.name = name;
  }
  
  // 类的方法
  greet(): void {
    console.log(`Hello, my name is ${this.name}!`);
  }
}
 
// 创建 'Person' 类的实例
const person = new Person('Alice');
 
// 调用对象的方法
person.greet();  // 输出: Hello, my name is Alice!

在这个例子中,我们定义了一个接口 Named 来约束具有 name 属性的对象。然后我们创建了一个 Person 类,它实现了这个接口,并拥有一个构造函数来初始化 name 属性。同时,我们定义了一个 greet 方法来输出问候语。最后,我们创建了一个 Person 类的实例,并调用了它的 greet 方法。