前言😏
笔者曾经被问道:TypeScript 中 type 和 interface 区别
我们看看AI的答案:
在 TypeScript 中,type
和 interface
都可以用来定义类型。它们的主要区别在于:type
可以定义任何类型,而 interface
只能定义对象类型。
具体来说,type
可以定义原始类型、联合类型、元组类型和函数类型等,而 interface
只能定义对象类型、类类型和函数类型。
下面是一些具体的区别:
type
可以定义原始类型、联合类型、元组类型和函数类型,而interface
只能定义对象类型、类类型和函数类型。
type MyType = boolean | number; // 原始类型和联合类型 interface MyInterface { x: number; y: number; } // 对象类型 type Point = [number, number]; // 元组类型 interface Shape { color: string; width: number; height: number; } // 对象类型 type HelloFunction = (name: string) => string; // 函数类型 interface GoodbyeFunction { (name: string): string; } // 函数类型
type
支持 extends 和交叉类型,而interface
只支持 extends。
type Base = { x: number }; type Derived = Base & { y: number }; type Merged = Base | { z: number }; interface Base { x: number; } interface Derived extends Base { y: number; }
interface
支持定义合并,即多个同名接口的成员会合并为同一个接口,而type
不支持。
interface Foo { x: number; } interface Foo { y: string; } const obj: Foo = { x: 1, y: "hello" };
总之,type
和 interface
都是用于定义类型的关键字,它们的主要区别在于 type
可以定义任何类型,而 interface
只能定义对象类型。
在选择使用哪种关键字时,应根据需要来确定使用范围和功能,以提高代码的可读性和可维护性。
😊以上就是AI的回答啦~
那么,对于没有深入研究且在实际开发中没有使用到 TypeScript 的我,在回答那个问题的时候自然是回答不上的,现在有了AI的加持,可以多学习了,不仅问了下AI上面那个问题的答案,并且让AI列举了十道关于TypeScript那些偏僻的面试题
以下是关于 TypeScript 的一些偏僻的面试题😝
1. 泛型约束中的 “extends” 关键字有哪些用法和含义?
在 TypeScript 中,“extends” 关键字在泛型约束中使用,用来指定泛型类型的类型范围和约束条件,可以用于:
1. 类型的范围约束
在泛型定义中,使用 “extends” 关键字,指定一个类型约束范围,确保泛型所接收的类型必须是一个指定的类型。
例如:
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; } loggingIdentity('123'); // 输出 3
上面的例子中,“T extends Lengthwise” 说明泛型变量 “T” 必须满足 “Lengthwise” 接口的约束(即具有 length 属性)。
2. 多重约束
可以针对一个泛型变量指定多个约束条件。
例如:
function copyFields<T extends U, U>(target: T, source: U): T { for (let id in source) { target[id] = (<T>source)[id]; } return target; } let x = { a:1, b: 2, c: 3, d: 4 }; copyFields(x, { b: 10, d: 20 }); //这个是可以的. copyFields(x, { e: 10 }); // error,因为 source 上不存在 a 或 b 属性
上面的例子中,“T extends U” 说明泛型变量 “T” 必须满足 “U” 类型的约束,从而确定了泛型变量 “T” 的类型范围。
总之,“extends” 关键字用于定义泛型类型的约束条件,可以指定类型或接口,也可以定义多重约束。在使用泛型的时候,可以通过对泛型变量进行约束,确保所传入的参数符合预期类型。
2. 什么是交叉类型(Intersection Types)?如何在 TypeScript 中定义和使用它们?
交叉类型(Intersection Types)是 TypeScript 中表示多个类型的交集的一种方式。
简单地说,它可以将多个类型合并成一个类型。例如,假设有两个类型 A 和 B:
interface A { propA: string; } interface B { propB: number; }
我们可以使用交叉类型将这两个类型合并成一个类型,定义一个新的类型 C:
type C = A & B;
交叉类型 C
包含了类型 A
和 B
中的所有属性。因此,变量 c
可以包含 propA
和 propB
两个属性:
const c: C = { propA: "hello", propB: 123 };
交叉类型也可以使用于继承:
class D implements A, B { propA = "hello"; propB = 123; }
在使用交叉类型时,需要注意以下几点:
- 只有需要合并类型的属性之间类型冲突时才需要使用交叉类型,否则使用普通类型即可。
- 交叉类型中所有类型的属性都必须满足相同的访问限制(public、private 或 protected)。
Union
类型和Intersection
类型的区别在于,Union
类型表示多个类型中的任意一个,而交叉类型表示多个类型的交集。
3. 请解释 “keyof” 关键字的含义和用法。
“keyof” 关键字是 TypeScript
中用来获取一个类型(通常是对象类型)所有键(即属性名)的名称的一种方式。
举个例子,假设有一个对象类型:
type Person = { name: string; age: number; gender: "male" | "female"; };
我们可以使用 “keyof” 关键字获取这个对象类型的所有键的名称:
type PersonKeys = keyof Person; // 等价于 type PersonKeys = "name" | "age" | "gender"
这意味着我们可以使用 PersonKeys
来定义一个函数的参数类型:
function getProp(obj: Person, key: keyof Person): any { return obj[key]; }
在上面的例子中,参数 key 的类型指定为 “keyof Person”,即表示参数 key 必须为 Person
中定义过的属性名,而不是其他任何字符串。
此外,“keyof” 关键字还可以用于泛型类型或条件类型:
type PersonPropTypes<T> = { [K in keyof T]: T[K] extends string ? K : never; };
在上面的例子中,我们使用了泛型 “T” 和 “keyof T”。“keyof T” 表示泛型 T 中所有属性名的联合类型,我们可以通过它来定义一个新的对象类型,该对象类型只包含泛型 T 中值为字符串类型的属性名。
总之,“keyof” 关键字是一种非常有用的 TypeScript
特性,它常用于为对象类型中的属性命名并且在编写通用代码时提供了更好的类型检查。
4. TypeScript 中的 “never” 类型有什么用途?请给出一个示例。
在 TypeScript 中,never
类型表示一个永远不会发生的值的类型。在实际应用中,never
类型常常用在联合类型或泛型中:
1. 当函数的返回类型为 never
时,表示该函数永远不会正常返回。
function throwError(message: string): never { throw new Error(message); }
2. 在泛型中使用 never
类型可以帮助我们确保某些类型不会被传递进来,进而让编译器帮我们避免一些可能出现的错误。
type NonNullable<T> = T extends null | undefined ? never : T; type MyRequired<T> = { [P in keyof T]-?: NonNullable<T[P]>; };
上面的代码定义了一个泛型 NonNullable
和一个接口 MyRequired
。其中,NonNullable
可以将 null
和 undefined
类型转化为 never
类型,而 MyRequired
可以将每个属性变为必需的,并且确保不会出现 null
或 undefined
。
总的来说,never
类型的主要用途是辅助开发人员进行类型检查和编写更加安全的代码。
【利用AI刷面试题】AI:十道不常见的TypeScript面试题(二)https://developer.aliyun.com/article/1426075