第38天:断言
#javascript #typescript #100daysofcode #day38

什么是类型的断言?

一种类型的断言告诉打字稿:“相信我,我知道的类型比您要多。”这就像开发人员的秘密握手,使您可以覆盖打字稿的类型推理并指定变量的类型。它们有两种口味:angle-bracket syntaxas关键字。

角度支架语法

let someValue: any = "hello, world";
let strLength: number = (<string>someValue).length;

在此示例中,我们告诉Typescript将someValue视为临时的字符串,以便我们可以访问其length属性。该语法在React项目或较旧的JavaScript代码库中更为常见。

as关键字

let someValue: any = "hello, world";
let strLength: number = (someValue as string).length;

通常优选as语法,因为它更可读性,不太容易在复杂代码中混淆。

不是无效断言

打字稿还支持一个特殊的断言,称为“非零断言”,由!代表。该断言告诉打字稿,变量不是nullundefined。当您确定存在一个值但不确定时,它可能会有所帮助。

function getLength(someValue: string | null | undefined) {
  return someValue!.length;
}

谨慎:在值实际上可以是nullundefined时,使用非零断言会导致运行时错误。它应该很少使用,并且只有当您绝对确定该值的存在时。

as const断言

as const断言是创建不变的对象和字面类型的强大工具。

让我们在行动中查看它:

const colors = {
    red: "RED",
    blue: "BLUE",
} as const; // Assertion

type Color = keyof typeof colors; // Color is "red" | "blue"

const primaryColor: Color = "red"; // Valid

在这里,as const确保colors被视为只读对象,而打字稿将Color视为字面类型。

ð§当不是使用类型断言

虽然类型的断言很有价值,但它们会带来风险。不小心使用它们会导致运行时错误或否定打字稿的类型检查。以下是要避免的一些情况:

  1. 忽略类型安全:仅在确定类型时使用断言。盲目断言类型可以隐藏错误。

  2. 避免任何类型:不要使用断言逃脱any类型,没有充分的理由。它打败了打字稿的目的。

  3. 替代解决方案:在诉诸断言之前,请考虑替代的打字稿诸如类型的守卫和缩小类型。

ð¶何时使用类型断言

类型断言在这些情况下最有帮助:

  • 与外部数据互动:处理来自API或用户输入(例如用户输入)的数据时,断言可以澄清类型。

  • 使用旧版代码:在较旧的或未经类似的代码库中,类型断言可以弥合Typescript和JavaScript之间的差距。

  • 缩小类型:当打字稿无法自动缩小类型时,断言可以为类型检查器提供提示。

例子

1.使用遗产代码

当您处理未型或松散键入的JavaScript代码时,类型断言可以帮助您逐渐引入打字稿而不从头重写所有内容。

let legacyData: any = fetchDataFromLegacyAPI();
let typedData: DataType = legacyData as DataType;

2. DOM操纵

使用文档对象模型(DOM)通常涉及类型铸造,因为属性和方法可以返回通用对象。

const element = document.getElementById("myElement") as HTMLInputElement;
element.value = "Hello, TypeScript!";

3.测试

在单元测试中,您可能需要模拟某些对象或值。类型的断言可以在这里方便地将其暂时投入到预期的类型。

const mockedService = new MockedService() as MyService;

4.接口和复杂类型

处理复杂的对象结构时,您可能需要主张类型以导航嵌套属性。

interface Person {
  name: string;
  address?: {
    street: string;
    city: string;
  };
}

const data: Person = {
  name: "John",
};

const city = (data.address as { city: string }).city;