跳到主要内容

数据类型

  1. 基本数据类型

    • number:表示数字类型,包括整数和浮点数。
    • string:表示字符串类型。
    • boolean:表示布尔类型,值为 truefalse
    • null:表示 null 值。
    • undefined:表示未定义的值。
    • symbol:表示唯一的、不可变的值,通常用于对象属性的键。
    • bigint:表示任意精度的整数。
  2. 复合数据类型

    • object:表示非原始数据类型,即除 numberstringbooleannullundefinedsymbolbigint 之外的所有类型。
    • array:表示数组类型。
    • tuple:表示元组类型,用于固定长度和固定类型的数组。
    • function:表示函数类型。
    • enum:表示枚举类型,一组有名字的常数集合。
    • any:表示任意类型,可以赋予任何类型的值,适用于不清楚变量类型的情况下。
  3. 高级数据类型

    • unknown:表示未知类型,与 any 类似,但更安全,需要进行类型检查或类型断言后才能使用。
    • never:表示永远不存在的值的类型,通常用于表示抛出异常、无限循环等情况。
    • void:表示没有任何类型,通常用于函数没有返回值时的标注。

除了这些基本的数据类型,TypeScript 还支持更复杂的类型,例如交叉类型、联合类型、类型别名、泛型等。

FAQ?

ts 中 any 和 unknown 有什么区别?

unknown 和 any 的主要区别是 unknown 类型会更加严格:在对 unknown 类型的值执行大多数操作之前,我们必须进行某种形式的检查。而在对 any 类型的值执行操作之前,我们不必进行任何检查。

举例说明:

let foo: any = 123;
console.log(foo.msg); // 符合TS的语法
let a_value1: unknown = foo; // OK
let a_value2: any = foo; // OK
let a_value3: string = foo; // OK

let bar: unknown = 222; // OK
console.log(bar.msg); // Error
let k_value1: unknown = bar; // OK
let K_value2: any = bar; // OK
let K_value3: string = bar; // Error

因为 bar 是一个未知类型(任何类型的数据都可以赋给 unknown 类型),所以不能确定是否有 msg 属性。不能通过 TS 语法检测;而 unknown 类型的值也不能将值赋给 any 和 unknown 之外的类型变量

总结

any 和 unknown 都是顶级类型,但是 unknown 更加严格,不像 any 那样不做类型检查,反而 unknown 因为未知性质,不允许访问属性,不允许赋值给其他有明确类型的变量。

TypeScript 中的枚举(Enum)是什么,如何定义和使用一个枚举?

  • TypeScript 中的枚举可以用来给一组相关的常量赋予一个有意义的名字,从而使代码更易读和维护。
  • 可以使用以下语法来定义一个枚举:
enum Color {
Red,
Green,
Blue,
}

上面的代码定义了一个名为 Color 的枚举,其中包含了三个成员:Red、Green 和 Blue。可以通过以下方式来使用枚举:

const color: Color = Color.Red;
console.log(color); // 0

TypeScript 中的交叉类型(Intersection Types)是什么?如何使用?

  • 交叉类型可以用来将多个类型合并为一个类型,新的类型将具有所有类型的特性。
  • 在 TypeScript 中可以使用 & 符号来定义交叉类型,以下是一个例子:
interface User {
name: string;
age: number;
}

interface Employee {
company: string;
position: string;
}

type Staff = User & Employee;

const staff: Staff = {
name: 'Tom',
age: 30,
company: 'Apple',
position: 'Engineer',
};

上面的代码中,定义了两个接口 User 和 Employee,分别表示用户和员工的信息。然后,使用 & 符号定义一个 Staff 类型,表示既是用户又是员工的新类型。最后,可以创建一个 Staff 类型的对象 staff,它既包含了 User 类型的属性,又包含了 Employee 类型的属性。

TypeScript 中的类型保护是什么?如何在代码中使用类型保护?

  • 类型保护可以用来在 TypeScript 中对一个变量的类型进行更精确的判断,从而避免在代码中出现类型错误。

  • 以下是一些 TypeScript 中常用的类型保护方法:

  • typeof 类型保护:使用 typeof 运算符可以判断一个变量的类型是否为 string、number、boolean、symbol 中的一种。

    function isNumber(value: unknown): value is number {
    return typeof value === "number";
    }
  • instanceof 类型保护:使用 instanceof 运算符可以判断一个对象是否属于某个类的实例。

    class Circle {
    radius: number;
    constructor(radius: number) {
    this.radius = radius;
    }
    }

    function isCircle(shape: unknown): shape is Circle {
    return shape instanceof Circle;
    }
  • in 类型保护:使用 in 运算符可以判断一个对象是否包含某个属性。

    interface Rectangle {
    width: number;
    height: number;
    }

    function isRectangle(shape: unknown): shape is Rectangle {
    return "width" in shape && "height" in shape;
    }
  • 自定义类型保护:通过一个函数来判断一个变量的类型是否符合要求。

    interface User {
    name: string;
    age: number;
    }

    interface Employee extends User {
    company: string;
    position: string;
    }

    function isEmployee(user: User): user is Employee {
    return "company" in user && "position" in user;
    }

上面的代码中,分别定义了四种类型保护方法,并且在相应的函数中使用了 is 关键字来说明这是一个类型保护函数,这样在使用的时候,TypeScript 就能更好地推断变量类型。

typescript 守护类型

TypeScript 的“守护类型”是指使用类型断言或类型保护来在运行时检查值的类型。它可以帮助在编译时减少类型错误,同时保持 JavaScript 的动态特性。

例如,在 TypeScript 中,您可以使用以下类型保护函数检查值的类型:

function isNumber(value: any): value is number {
return typeof value === "number";
}

let value: any = 42;

if (isNumber(value)) {
console.log("Value is a number:", value.toFixed(2));
} else {
console.log("Value is not a number.");
}

在这个例子中,isNumber函数接受一个值作为参数,并返回一个布尔值。如果参数的类型是number,则返回true;否则返回false。在if语句中,我们使用isNumber函数来检查value的类型。如果value是一个数字,我们就调用toFixed方法打印出该数字的值,否则我们打印一个错误消息。

这种基于类型保护函数的“守护类型”可以让您在编译时发现类型错误,并提供更好的类型安全保证。

typescript 中的 is 关键字有什么用?

在 TypeScript 中,is 关键字通常用于自定义类型守卫(Type Guards)。类型守卫是一种用来在运行时检查变量的类型的技术,它可以帮助开发者在代码中更准确地处理不同类型的数据。

// 自定义类型守卫函数,用于检查是否是数组类型
function isArray(value: any): value is Array<any> {
return Array.isArray(value);
}

// 使用自定义类型守卫进行类型检查
let arr: any = [1, 2, 3];
if (isArray(arr)) {
console.log("arr is an array");
} else {
console.log("arr is not an array");
}

如何将 unknown 类型指定为一个更具体的类型?

  • 使用 typeof 进行类型判断(这些缩小类型范围的技术都有助于 TS 基于控制流程下的类型分析)
function unknownToString(value: unknown): string {
if (typeof value === "string") {
return value;
}

return String(value);
}
  • 对 unknown 类型使用类型断言 要强制编译器信任类型为 unknown 的值为给定类型,则可以使用类型断言:
const value: unknown = "Hello World";
const foo: string = value; // Error
const bar: string = value as string; // OK

断言错了时语法能通过检测,但是运行的时候就会报错了!

const value: unknown = "Hello World";

const bar: number = value as number; // runtime Error

never 和 void 的区别?

  • void 表示没有任何类型(可以被赋值为 null 和 undefined)。
  • never 表示一个不包含值的类型,即表示永远不存在的值。
  • 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。