【TypeScript】30+问答

目录

问题1 什么是 TypeScript?

问题2 什么是显式和隐式类型分配?

问题3 TypeScript 中 any、unknown 和 never 之间的区别?

问题4 如何给出数组的类型?

问题5 数组中的类型推断是什么?

问题6 什么是元组?

问题7 什么是只读元组?

问题8 如何给出对象的类型?

问题9 如何在对象中拥有可选属性?

问题10 解释 TypeScript 中的枚举?

问题11 什么是字符串枚举?

问题12 什么是类型别名?

问题13 什么是接口?

问题14 如何扩展接口?

问题15 什么是联合类型?

问题16 如何在函数中给出返回类型?

问题17 如何在函数中给出参数类型?

问题18 如何在函数中提供可选参数、默认参数和其余参数?

问题19 TypeScript 中的转换是什么?

问题20 如何在类中给出变量的类型?

问题21 TypeScript 类中的公共、私有和受保护是什么?

问题22 TypeScript 中引用类时的 readonly 关键字是什么?

问题23 如何在 TypeScript 类中实现覆盖?

问题24 什么是抽象类?

问题25 什么是 Singleton 类。

问题26 TypeScript中的泛型是什么

问题27 什么是 Partial

问题28 什么是Required

问题29 什么是Record

问题30 什么是 Omit

问题31 什么是 Pick

问题32 什么是排除

问题33 什么是只读

问题34 什么是空值合并


问题1 什么是 TypeScript?

TypeScript 是 JavaScript 的一个超集,您可以在其中向 JavaScript 添加类型。JavaScript 是一种松散类型的语言,这会导致生产代码中出现许多类型错误。使用 TypeScript,开发人员甚至可以在运行代码之前捕获这些错误。

问题2 什么是显式和隐式类型分配?

显式意味着写出类型。如下所示:

let name: string = "张三";

隐式意味着 TypeScript 将根据值猜测类型。如下所示,类型将被视为数字

let age = 41;
问题3 TypeScript 中 any、unknown 和 never 之间的区别?

any 类型用于分配任何类型的变量。即使您重新分配另一种类型,也不会出错。如下所示:

let x: any = 10;x = 'hello'; // No TypeScript errorconsole.log(x.toUpperCase()); // No TypeScript error

类型 unknown 比类型 any 更好,因为它要求我们在对值执行操作之前检查类型。如下所示:

let y: unknown = 10;// 使用 y 作为数字if (typeof y === 'number') {console.log(y.toFixed(2));}

该类型 never 表示永远不会发生的值。它通常用于无法正确返回的函数的返回语句。如下所示:

function throwError(message: string): never {throw new Error(message);}
问题4 如何给出数组的类型?

对于类型数组,我们需要给出如下类型。在下面的例子中,数组只能包含字符串类型。​​​​​​​

const names : string [] = [ "张三" , "李四" , " 王五" ]; names.push ( "赵六" ); // 无错误

我们还可以使用 readonly 关键字,以防止数组被更改。​​​​​​​

const names: readonly string[] = ["张三", "李四", "王五"];names.push("赵六"); //  错误:类型readonly string[]上不存在属性push。
问题5 数组中的类型推断是什么?

如果我们不给数组指定任何类型,它将推断其类型。如下所示:​​​​​​​

const numbers = [1, 2, 3]; // 推断为类型 number[]numbers.push(4); 
问题6 什么是元组?

它是一个具有预定义长度和类型的类型数组。它在提供具有不同类型的混合数组类型时非常有用,如下所示:​​​​​​​

let ourTuple: [number, boolean, string];//  正确初始化ourTuple = [5, false, '这里写点。。。'];
问题7 什么是只读元组?

如果我们不将元组设为只读,我们可以向定义的元组添加更多项目,而 TypeScript 不会抛出任何错误,如下所示:​​​​​​​

let ourTuple: [number, boolean, string];// 正确初始化ourTuple = [5, false, '这里写点。。。'];//不安全ourTuple.push('增加点。。。');

现在,为了修复它,我们在类型前使用关键字 readonly。​​​​​​​

let ourTuple: readonly [number, boolean, string];ourTuple = [5, false, '这里写点。。。'];//  由于是只读,因此引发错误ourTuple.push('Coding Hero took a day off');
问题8 如何给出对象的类型?

我们可以通过创建另一个对象(如结构)并指定对象中的键和键的类型来给出对象的类型。​​​​​​​

const car: { brand: string, model: string, year: number } = {  brand: "华为",  model: "pura 70",  year: 2024};
问题9 如何在对象中拥有可选属性?

要提供可选属性或键,我们需要在键后添加 ?,如下所示。​​​​​​​

const car: { brand: string, model: string, year?: number } = {  brand: "华为",  model: "pura 70"};
问题10 解释 TypeScript 中的枚举?

枚举是一种常量变量。您只能使用其中的值。默认情况下,值是数字,从 0 开始并以 1 为增量。​​​​​​​

enum allDirections { North, East, South, West }let currentDirection = allDirections.North;console.log(currentDirection);// logs 0
问题11 什么是字符串枚举?

如果您希望枚举包含字符串而不是默认数字,则需要指定相同的内容。​​​​​​​

enum allDirections {  North = "北",  East = "东",  South = "南",  West = "西"};let currentDirection = allDirections.North;console.log(currentDirection);// logs "北"
问题12 什么是类型别名?

它们允许使用自定义名称定义类型,并且可以用于所有原始类型(如字符串和数字)以及复杂类型(如对象和数组)。如下所示:​​​​​​​

type Year = numbertype Type = stringtype Model = stringtype Car = {  year: Year,  type: Type,  model: Model}const carYear: Year = 2024const carType: Type = "幻影"const carModel: Model = "劳斯莱斯"const car: Car = {  year: Year,  type: Type,  model: Model};
问题13 什么是接口?

接口类似于类型,但只能用于对象。如下所示:​​​​​​​

interface Square {  length: number}const square: Square {  length: 20}
问题14 如何扩展接口?

可以使用 extend 关键字来扩展接口。如下所示:

interface Square {  length: number}interface ColorSquare extends Square {  color: string}const square: ColorSquare {  length: 20,  color: blue}
问题15 什么是联合类型?

当属性可以有多个值(如字符串或数字)时,使用联合类型。因此,它们也称为 OR,使用 | 符号。如下所示:​​​​​​​

function printSucessCode(code: string | number) {  console.log(`成功码 ${code}.`)}printSucessCode(200);printSucessCode('200');
问题16 如何在函数中给出返回类型?

我们可以在函数名称后使用 : 符号来指定函数的返回类型。如下所示:​​​​​​​

function getSum(): number {  return 24;}function printMessage(): void {  console.log("欢迎");}
问题17 如何在函数中给出参数类型?​​​​​​​
function sum(a: number, b: number) {  return a + b;}
问题18 如何在函数中提供可选参数、默认参数和其余参数?

使用默认参数,我们可以将参数标记为可选。像这样,其中 c 是可选的,用 ? 表示。​​​​​​​

function substract(a: number, b: number, c?: number) {  return a - b -(c || 0);}

默认值(ES6 功能)位于类型之后/如下所示:​​​​​​​

function multiply(a: number, b: number=10) {  return a * b;}

其余参数(ES6 功能)被赋予数组类型,因为它们转换数组中传递的项目。如下所示:​​​​​​​

function add(a: number, b: number, ...rest: number[]) {  return a + b + rest.reduce((acc, curr) => acc+ curr, 0);}
问题19 TypeScript 中的转换是什么?

强制转换是覆盖变量类型的过程。如下例所示,类型未知,但在使用 as 关键字时会变成字符串。​​​​​​​

let y: unknown = '欢迎';console.log((y as string).length);

我们也可以用 <> 代替 as。两者意思相同。​​​​​​​

let y: unknown = '欢迎';console.log((<string>y).length);
问题20 如何在类中给出变量的类型?

在这个简单的例子中,我们在类中将名称的类型指定为字符串。​​​​​​​

class Developer {  name: string;}const dev = new Developer();dev.name = "张三";
问题21 TypeScript 类中的公共、私有和受保护是什么?

以下是所有内容的含义

  • public — 如果未提及则为默认值,并允许从任何地方访问类成员。

  • private- 类成员只能从类内部访问。

  • protected — 类成员可以由其自身或继承的类访问。

public示例:​​​​​​​

class Developer {public name: string;}const dev = new Developer();dev.name = "张三";

private 的示例。请注意,get 函数来访问 private 成员。​​​​​​​

class Developer {private name: string;public constructor(name: string) {  this.name = name;}public getName(): string {  return this.name;}}const dev = new Developer("张三");console.log(person.getName());

我们也可以编写上述的简写版本,即直接在构造函数中添加私有变量。​​​​​​​

class Developer {public constructor(private name: string) {}public getName(): string {  return this.name;}}const dev = new Developer("张三");console.log(person.getName());

对于受保护的,我们需要从基类继承,使用 extends 关键字即可。此外,我们还可以使用 implements 关键字从接口获取类的数据。​​​​​​​

interface Shape {getArea: () => number;}
class Rectangle implements Shape {  public constructor(protected width: number, protected height: number) {}  public getArea(): number {  return this.width * this.height;}}
class Square extends Rectangle {  public constructor(width: number) {  super(width, width);}}const mySq = new Square(20);console.log(mySq.getArea()); //Logs 400
问题22 TypeScript 中引用类时的 readonly 关键字是什么?

readonly 关键字可防止类成员被更改。我们通常将 readonly 与私有或受保护成员一起使用。

在下面的例子中,名称在初始定义之后不能更改。​​​​​​​

class Developer {private readonly name: string;public constructor(name: string) {  this.name = name;}public getName(): string {  return this.name;}}const dev = new Developer("张三");console.log(person.getName());
问题23 如何在 TypeScript 类中实现覆盖?

覆盖是一个重要的 OOP 概念,继承的类会覆盖其父类中的函数(大多数情况下)。我们通过在函数中使用 override 关键字来实现相同的功能。​​​​​​​

interface Shape {  getArea: () => number;}
class Rectangle implements Shape {  public constructor(protected readonly width: number, protected readonly height: number) {}
  public getArea(): number {    return this.width * this.height;  }
  public toString(): string {    return `矩形宽度为 ${this.width} 且高度为 ${this.height}`;  }}
class Square extends Rectangle {  public constructor(width: number) {    super(width, width);  }
  public override toString(): string {    return `正方形宽度 ${this.width}`;  }}
const square = new Square(20);console.log(square.toString()); 
问题24 什么是抽象类?

当我们用 abstract 关键字声明基类时,我们不能为其创建对象。在这种方法中,我们通常在子类中使用抽象类的方法。

另外,如果我们在基类中的函数前面添加 abstract 关键字,则需要在子类中创建它。但对于非抽象函数则不需要这样做。​​​​​​​

abstract class Polygon {  public abstract getArea(): number;
  public toString(): string {    return `多边形面积 ${this.getArea()}`;  }}
class Rectangle extends Polygon {  public constructor(protected width: number, protected height: number) {    super();  }
  public getArea(): number {    return this.width * this.height;  }}
const rect = new Rectangle(10,20);console.log(rect.getArea()); // Logs - 200console.log(rect.toString());// Logs - 多边形面积 200
问题25 什么是 Singleton 类。

Singleton 类是特殊类型的类,用于确保我们只有一个类的实例。

为了创建此类,我们将构造函数设为私有,以防止使用 new 来创建对象。接下来,我们使用静态方法创建该类的单个实例。示例如下:​​​​​​​

class Coder {  private static instance: Coder;
  private constructor() {}
  static getInstance() {    if (this.instance) {      return this.instance;    }    this.instance = new Coder();    return this.instance;  }}
const c1 = Coder.getInstance();const c2 = Coder.getInstance();
console.log(c1 === c2); //Logs - true
问题26 TypeScript中的泛型是什么

泛型允许创建类型变量,这些变量可用于创建类、函数和类型别名。在这里,我们不必定义它们使用的类型。

函数示例:​​​​​​​

function createArray<S, T>(v1: S, v2: T): [S, T] {return [v1, v2];}console.log(createArray<string, number>('JS', 42)); //Logs - ['JS', 42]

类示例:

class GenericClass<T> {  private _value: T | undefined;
  constructor(private name: string) {}
  public setValue(value: T) {    this._value = value;  }
  public getValue(): T | undefined {    return this._value;  }
  public toString(): string {    return `${this.name}: ${this._value}`;  }}      const value = new GenericClass<number>('theNum');2value.setValue(10);console.log(value.toString()); // theNum: 10
问题27 什么是 Partial

Partial 将对象中的所有属性更改为可选。在下面的示例中,界面具有宽度和高度。但是,我们只给出了宽度,因为我们已将 rectPart 设为 Partial。

interface Rectangle {width: number;height: number;}
let rectPart: Partial<Rectangle> = {};rectPart.width = 100;console.log(rectPart); // Logs - { width: 100 }
问题28 什么是Required

Required将对象中的所有属性更改为必需。在下面的示例中,接口中的里程是可选的。但是,当我们在创建对象时将其设为必需时,我们被迫提供里程。

interface Car {make: string;model: string;mileage?: number;}
let myCar: Required<Car> = {make: '劳斯莱斯',model: '幻影',mileage: 20 // 强制定义};console.log(myCar); // Logs - { make: '斯', model: '幻影', mileage: 20 }
问题29 什么是Record

Record是定义对象的快捷方式,具有指定的键类型和值类型。

const nameAgeObj: Record<string, number> = {'张三': 42,'李四': 41};console.log(nameAgeObj);// Logs - { 张三: 42, 李四: 41 }
问题30 什么是 Omit

Omit 会从任何对象类型中删除键。如以下示例所示,omit 已从类型中删除 age 和 location,但无法定义。

interface Coder {name: string;age: number;location?: string;}
const nabs: Omit<Coder, 'age' | 'location'> = {name: '张三'};console.log(nabs); // Logs - { name: '张三' }
问题31 什么是 Pick

Pick 会从任何对象中删除除指定键之外的所有键。如以下示例所示,pick 已从类型中删除 age 和 location,但无法定义。

interface Coder {name: string;age: number;location?: string;}
const nabs: Pick<Coder, 'name'> = {name: '张三'};console.log(nabs); // Logs - { name: '张三' }
问题32 什么是排除

排除用于从联合中删除类型。如以下示例中所示,布尔值无法使用,因为它已被排除。

type Marks = string | number | boolean;const value: Exclude<Marks, boolean> = '56';console.log(typeof value); // Logs - string
问题33 什么是只读

Readonly 用于创建一旦赋值就无法修改的类型。如下例所示,一旦我们为 person 对象赋值,就无法更改。

interface Person {name: string;age: number;}const person: Readonly<Person> = {name: "张三",age: 42,};person.name = 'Parag'; // Logs error
问题34 什么是空值合并

空值合并用于处理 null 或 undefined 时具有回退功能的表达式。它与 ?? 运算符一起使用。

如下例所示,里程可以是数字、空值或未定义。这里,当值为空值或未定义时,我们使用 ?? 使其为 NA。

function showMileage(mileage: number | null | undefined) {console.log(`Mileage: ${mileage ?? 'NA'}`);}
showMileage(null); // Logs 'Mileage: NA'showMileage(0); // Logs 'Mileage: 0'showMileage(undefined); // Logs 'Mileage: NA'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值