面向 Java/C# 程序员的 TypeScript


在本教程中,我们将讨论 TypeScript,这是一个非常适合拥有 C# 和 Java 等静态类型语言经验的程序员的选项。我们可以从 TypeScript 的类型系统中受益,它提供了改进的代码补全、更早的错误检测以及程序不同部分之间更清晰的通信。务必记住,TypeScript 基于 JavaScript,它与传统的 OOP 语言有一些根本区别。通过理解这些差异,我们可以避免从 C#/Java 转向 TypeScript 的程序员可能犯的一些常见错误。

语法

用户可以使用以下语法在 TypeScript 中创建变量:

let variableName: type = value;

在此语法中,`let` 关键字用于声明变量,后跟变量名、冒号和变量的数据类型。最后,使用等号赋值变量的值。

TypeScript 的特性

以下是 Java/C# 程序员应该了解的 TypeScript 的一些特性:

TypeScript 和 JavaScript 入门

建议在深入学习 TypeScript 之前先了解 JavaScript。这将帮助我们编写更好的 JavaScript 代码,并避免从其他语言过渡过来的程序员可能犯的一些常见错误。此外,值得注意的是,TypeScript 使用与 JavaScript 相同的运行时,因此任何关于 JavaScript 的资源也可以应用于 TypeScript 程序。

TypeScript 中的类和面向对象编程

在 TypeScript 中,类是一种将数据和函数组合到可重用结构中的方法。但是,与 C# 和 Java 不同,在 TypeScript 中,类不是组织代码的必需项,也可以使用自由函数。

如果我们选择使用类,TypeScript 提供了许多特性,例如接口、继承和静态方法。这使得在 TypeScript 中编写面向对象代码更容易。但是,重要的是要理解类只是 TypeScript 工具箱中的一个工具,在某些情况下使用它们是可以的。

自由函数和静态类

在 TypeScript 中,我们不需要使用像 C# 和 Java 中常用的单例或静态类这样的构造。相反,当自由函数(与类无关的函数)和类对我们尝试解决的问题有意义时,我们可以使用它们。这使我们能够更灵活地组织代码。

名义具体类型系统和类型作为集合

在 C# 和 Java 等一些编程语言中,每个值或对象都只有一个由类或原始类型定义的精确类型。这称为“名义具体类型系统”,这意味着类型在运行时存在,并通过它们的声明相关联。

然而,在 TypeScript 中,最好将类型视为共享某些共同特征的一组值。类型不是基于显式声明,而是基于它们的结构以及与其他类型的关系。这被称为“类型作为集合”方法。

将类型视为集合允许进行更自然的运算,例如组合或相交类型,这对于一个值可以同时属于多个类型的情况很有用。TypeScript 提供了几种使用集合论方式处理类型的方法,使其成为编写灵活且表达力强的代码的有力工具。

结构类型及其在 TypeScript 中的结果

TypeScript 中的结构类型允许更大的灵活性和动态编程,因为只要对象和函数具有相同的结构,就可以互换使用它们。这可以使代码更易于重用和重构。

但是,如果对象的结构或函数在没有警告的情况下发生变化,则也可能导致意外行为,从而导致错误或类型不匹配。因此,在使用结构类型时,务必牢记潜在的风险和好处,并注意对象和函数的结构。

示例 1

在这个例子中,我们使用对象字面量语法创建了两个对象,一个人和一个员工,它们具有不同的属性。一个人具有姓名和年龄属性,而员工具有姓名、年龄和职位属性。

接下来,我们使用具有姓名和年龄属性的对象接口定义了一个 Person 类型。然后,我们定义了一个 printPerson 函数,它接受 Person 类型的参数并将消息记录到控制台。

最后,我们使用 person 和 employee 对象作为参数两次调用 printPerson 函数。由于这两个对象都具有与 Person 类型匹配的姓名和年龄属性,因此可以将它们作为参数传递给 printPerson 函数而不会出错。

用户可以在输出中观察到,printPerson 函数正确地将 person 和 employee 对象的姓名和年龄记录到控制台。

Open Compiler
let person = { name: "John", age: 30 }; let employee = { name: "Mary", age: 25, jobTitle: "Software Engineer" }; type Person = { name: string; age: number }; function printPerson(person: Person) { console.log(`${person.name} is ${person.age} years old.`); } printPerson(person); printPerson(employee);

编译后,它将生成以下 JavaScript 代码:

Open Compiler
var person = { name: "John", age: 30 }; var employee = { name: "Mary", age: 25, jobTitle: "Software Engineer" }; function printPerson(person) { console.log("".concat(person.name, " is ").concat(person.age, " years old.")); } printPerson(person); printPerson(employee);

输出

以上代码将产生以下输出:

John is 30 years old.
Mary is 25 years old.

示例 2

在这个例子中,我们创建了一个名为 Stack 的泛型类,它可以用来在 TypeScript 中实现堆栈数据结构。该类有一个类型参数 T,它表示将存储在堆栈中的元素的类型。

接下来,我们定义了一些可以用来操作堆栈的方法,例如 push、pop 和 isEmpty。push 方法接受类型为 T 的参数并将其添加到堆栈顶部。pop 方法删除并返回堆栈顶部的元素,而 isEmpty 方法检查堆栈是否为空。

最后,我们创建了一个 Stack 类的实例,其类型参数为字符串,并使用 push 方法向堆栈中添加了一些元素。然后,我们调用 pop 方法从堆栈中删除元素并将输出记录到控制台。

用户可以在输出中观察到,pop 方法返回字符串类型的元素,这是传递给 Stack 类的类型参数。

Open Compiler
class Stack<T> { private items: T[] = []; push(item: T): void { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } isEmpty(): boolean { return this.items.length === 0; } } const stringStack = new Stack<string>(); stringStack.push("Hello"); stringStack.push("World"); stringStack.push("!"); while (!stringStack.isEmpty()) { const item = stringStack.pop(); console.log(item); }

编译后,它将生成以下 JavaScript 代码:

Open Compiler
var Stack = /** @class */ (function () { function Stack() { this.items = []; } Stack.prototype.push = function (item) { this.items.push(item); }; Stack.prototype.pop = function () { return this.items.pop(); }; Stack.prototype.isEmpty = function () { return this.items.length === 0; }; return Stack; }()); var stringStack = new Stack(); stringStack.push("Hello"); stringStack.push("World"); stringStack.push("!"); while (!stringStack.isEmpty()) { var item = stringStack.pop(); console.log(item); }

输出

以上代码将产生以下输出:

!
World
Hello

总之,TypeScript 是一种强大的语言,它提供了 Java/C# 程序员可以从中受益的多种功能。通过学习 JavaScript 和 TypeScript,开发人员可以编写更高效、可扩展和易于维护的代码。

更新于:2023年8月21日

浏览量:269

启动您的 职业生涯

通过完成课程获得认证

开始
广告