百科狗-知识改变命运!
--

新学 TypeScript 的 JavaScript 程序员 - TypeScript 介绍

是丫丫呀1年前 (2023-11-21)阅读数 14#技术干货
文章标签类型

新学 TypeScript 的 JavaScript 程序员

TypeScript 与 JavaScript 有着不同寻常的关系。TypeScript 提供了 JavaScript 的所有功能,并在这些功能之上添加了一层: TypeScript 的类型系统。例如,JavaScript 提供了诸如stringnumber这样的原始类型,但它不检查你在赋值时与类型是否匹配。TypeScript 提供了这样的功能。

新学 TypeScript 的 JavaScript 程序员 - TypeScript 介绍

这意味着你现有的运行良好的 JavaScript 代码也是 TypeScript 代码。TypeScript 的主要好处是,它可以检查代码中的意外行为,从而降低出现错误的机会。

类型推断

TypeScript 可以识别 JavaScript 语言,在许多情况下可以推断类型。例如,在创建变量并将其赋值给特定值时, TypeScript 将使用该值作为其类型。

let helloWorld = "Hello World";        
let helloWorld: string

通过感知 JavaScript 的工作原理,TypeScript 可以构建一个接受 JavaScript 代码但具有类型的类型系统。这个类型系统使得我们不需要添加额外的字符来显式地指定类型。在上面的例子中,TypeScript就是这样知道helloWorldstring类型的。

你可能已经在 Visual Studio Code 中编写了 JavaScript,并已使用了编辑器的自动补全功能。Visual Studio Code 使用了 TypeScript 的引擎,以便更容易地处理 JavaScript。

定义类型

你可以在 JavaScript 中使用各种各样的设计模式。然而,某些设计模式使得类型难以自动推断(例如,使用动态编程的模式)。为了使类型推断涵盖这些情况, TypeScript 支持扩展 JavaScript 语言,它可以让 TypeScript 知道如何去推断类型。

例如,要创建具有推断类型的对象,该类型包括name: stringid: number,你可以这么写:

const user = { name: "Hayes", id: 0,
};

你可以使用interface关键字声明显式地描述此对象的内部数据的类型(译者注:下文可能译为“结构”):

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

然后你可以声明一个符合此接口(interface)的 JavaScript 对象,在变量声明后使用像: TypeName这样的语法:

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


const user: User = {
  name: "Hayes",
  id: 0,
}; 

如果提供的对象与提供的接口不匹配,TypeScript 将警告:

interface User {
  name: string;
  id: number;
}
 
const user: User = {
  username: "Hayes",
Type '{ username: string; id: number; }' is not assignable to type 'User'.
  Object literal may only specify known properties, and 'username' does not exist in type 'User'.
  id: 0,
};

由于 JavaScript 支持类和面向对象编程,TypeScript 也支持。你可以将接口声明与类一起使用:

interface User {
  name: string;
  id: number;
}
 
class UserAccount {
  name: string;
  id: number;
 
  constructor(name: string, id: number) {
    this.name = name;
    this.id = id;
  }
}
 
const user: User = new UserAccount("Murphy", 1);

您可以使用接口对参数进行注释,并将值返回给函数:

interface User {
  name: string;
  id: number;
}
// ---分割线---
function getAdminUser(): User {
  //...
}
 
function deleteUser(user: User) {
  // ...
}

JavaScript 中已经有一些基本类型可用:booleanbigintnullnumberstringsymbol undefined,它们都可以在接口中使用。TypeScript 将此列表扩展为更多的内容,例如any(允许任何类型)、unknown(确保使用此类型的人声明类型是什么)、never(这种类型不可能发生)和void(返回undefined或没有返回值的函数)。

构建类型有两种语法:接口和类型。你应该更喜欢interface。当需要特定功能时使用type


组合类型

使用 TypeScript,可以通过组合简单类型来创建复杂类型。有两种流行的方法可以做到这一点:联合和泛型。

联合

使用联合,可以声明类型可以是许多类型中的一种。例如,可以将boolean类型描述为truefalse

type MyBool = true | false;

_注意:_如果将鼠标悬停在上面的MyBool上,您将看到它被归类为boolean。这是结构化类型系统的一个属性。下面有更加详细的信息。

联合类型的一个流行用法是描述string或者number的字面量的合法值。

type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;

联合也提供了一种处理不同类型的方法。例如,可能有一个函数处理array或者string

function getLength(obj: string | string[]) {
  return obj.length;
}

要了解变量的类型,使用typeof

类型推断语句
stringtypeof s ==="string"
numbertypeof n ==="number"
booleantypeof b ==="boolean"
undefinedtypeof undefined ==="undefined"
functiontypeof f ==="function"
arrayArray.isArray(a)

例如,你可以使函数根据传递的是字符串还是数组返回不同的值:

function wrapInArray(obj: string | string[]) {
  if (typeof obj === "string") {
    return [obj];
            
(parameter) obj: string
  }
  return obj;
}

泛型

泛型为类型提供变量。一个常见的例子是数组。没有泛型的数组可以包含任何内容。带有泛型的数组可以描述数组包含的值。

type StringArray = Array;
type NumberArray = Array;
type ObjectWithNameArray = Array;

你可以声明自己使用泛型的类型:

interface Backpack {
  add: (obj: Type) => void;
  get: () => Type;
}
 
// 这一行是一个简写,可以告诉 TypeScript 有一个常量,叫做`backpack`,并且不用担心它是从哪
// 里来的。
declare const backpack: Backpack;
 
// 对象是一个字符串,因为我们在上面声明了它作为 Backpack 的变量部分。
const object = backpack.get();
 
// 因为 backpack 变量是一个字符串,不能将数字传递给 add 函数。
backpack.add(23);
Argument of type 'number' is not assignable to parameter of type 'string'.


结构化的类型系统(structural type system)

TypeScript 的一个核心原则是类型检查基于对象的属性和行为(type checking focuses on the shape that values have)。这有时被叫做“鸭子类型”或“结构类型”(structural typing)。

在结构化的类型系统当中,如果两个对象具有相同的结构,则认为它们是相同类型的。

interface Point {
  x: number;
  y: number;
}
 
function logPoint(p: Point) {
  console.log(`${p.x}, ${p.y}`);
}
 
// 打印 "12, 26"
const point = { x: 12, y: 26 };
logPoint(point);

point变量从未声明为Point类型。但是,在类型检查中,TypeScript 将point的结构与Point的结构进行比较。它们的结构相同,所以代码通过了。

结构匹配只需要匹配对象字段的子集。

const point3 = { x: 12, y: 26, z: 89 };
logPoint(point3); // 打印 "12, 26"
 
const rect = { x: 33, y: 3, width: 30, height: 80 };
logPoint(rect); // 打印 "33, 3"
 
const color = { hex: "#187ABF" };
logPoint(color);
Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'.
  Type '{ hex: string; }' is missing the following properties from type 'Point': x, y

类和对象确定结构的方式没有区别:

interface Point {
  x: number;
  y: number;
}
 
function logPoint(p: Point) {
  console.log(`${p.x}, ${p.y}`);
}
// ---分割线---
class VirtualPoint {
  x: number;
  y: number;
 
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}
 
const newVPoint = new VirtualPoint(13, 56);
logPoint(newVPoint); // 打印 "13, 56"

如果对象或类具有所有必需的属性,则 TypeScript 将表示是它们匹配的,而不关注其实现细节。

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)