2.3 拓展知识了解 TypeScript 中的高级概念
什么是打字稿?
TypeScript 由 Microsoft 创建和维护,是 JavaScript 的超集,这意味着所有功能性 JavaScript 代码在 TypeScript 下都是有效的。该语言可以理解为“用于应用程序级开发的 JavaScript”,主要关注两个方面:
- 提供从未来 JavaScript 引擎到当前 JavaScript 引擎的功能
- 为 JavaScript 提供类型系统
TypeScript 的组件通常是语言本身,本质上是 JavaScript 加上附加的功能和语法,将代码转换为 JavaScript 的编译器,以及在编译器管道末端提供类似编辑器的应用程序的语言服务。
那么,为什么要使用 TypeScript?
- 打字: TypeScript 提供静态打字,微软和谷歌等许多大型团队发现这有助于简化开发过程。
- 面向对象编程: TypeScript 支持面向对象的编程概念,如接口、继承、类等。
- **编译:**与解释性语言 JavaScript 不同,TypeScript 会为您编译代码并查找编译错误,从而更容易调试。
安装 TypeScript
在我们深入研究 TypeScript 之前,请确保您已成功安装 TypeScript。获取 TypeScript 工具的两种主要方法是通过 npm(Node.js 包管理器)或安装 TypeScript 的 Visual Studio 插件。
NPM:
安装
> npm install -g typescript
编译
> tsc helloworld.ts
TypeScript 的优点和局限性
TypeScript
JavaScript 是一种动态类型语言,这意味着类型错误仅在运行时才被发现。对于从事复杂项目的大型团队来说,这可能是一个显着的缺点,因为事先发现代码的所有错误会容易得多。
TypeScript 提供可选的静态类型,因此变量不能更改其类型并且只能接受某些值。这种类型有助于 TypeScript 编译器发现更多错误,以便开发人员使用不易出错的代码。类型保护通过使其更具可读性和更容易重构来为代码创建更多结构。
IDE 支持
因为 TypeScript 提供了类型,所以文本编辑器和集成开发环境 (IDE) 可以为开发人员提供更多有用的信息。这些环境可以提供自动完成、代码导航、错误标记等功能,以提高团队的生产力。
一些支持 TypeScript 3 的流行环境:
- Microsoft Visual Studio
- WebStorm
- Visual Studio Code
- Atom
- Eclipse
浏览器兼容性
浏览器兼容性是 TypeScript 提供的强大功能之一。TypeScript 编译器会转换您的代码,使其与所有现代浏览器兼容。这种兼容性是因为编译器能够将 TypeScript 代码翻译成所有设备、平台和浏览器都支持的 vanilla JS。
尽管使用 TypeScript 有很多优点,但它并不是一个完美的解决方案。提高代码可读性的一个缺点是您必须编写更多代码,这可能会增加您的开发时间。与使用原生 JavaScript 相比,它还增加了 TypeScript 文件的大小。
严格类型简介
现在我们已经了解了 TypeScript 所提供的功能,让我们深入了解一些使 TypeScript 成为强大工具的更高级的概念。
noImplicitAny
根据文档, 的定义noImplicitAny
是“在任何隐含的任何类型的表达式和声明上引发错误”。
这意味着只要 TypeScript 可以推断类型,如果您允许noImplicitAny
. 这个例子可以通过传递函数参数来看到。
|
|
在上面的代码中,函数**的有效参数是print
什么?**如果你没有为函数参数添加类型,TypeScript 将分配 type 的参数any
,这将关闭类型检查。
对于喜欢代码安全的开发人员,他们可以使用noImplicityAny
,这将通知他们在代码中键入的任何可能性any
。让我们看看使用相同的print
功能会发生什么。
function print(arg) { // Error : someArg has an implicit `any` type
send(arg);
}
要修复错误,您可以注释函数参数。
function print(arg: number) { // Error : someArg has an implicit `any` type
send(arg);
}
但是如果你仍然想要类型any
,你可以显式地将参数标记为any
。
function print(arg: any) { // Error : someArg has an implicit `any` type
send(arg);
}
unknown
unknown
类型与类型相似之处在于any
所有类型都可分配给any
andunknown
类型,但区别在于该any
类型可分配给任何其他类型,但该unknown
类型不可分配给任何其他类型。区别可能是一个令人困惑的概念,所以让我们看一个例子。
function example1(arg: any) {
const a: str = arg; // no error
const b: num = arg; // no error
}
function example2(arg: unknown) {
const a: str = arg; // 🔴 Type 'unknown' is not assignable to type 'string'.(2322)
const b: num = arg; // 🔴 Type 'unknown' is not assignable to type 'number'.(2322)
}
一个变量arg
被传递给这两个函数,它们的类型可以是string
、number
或其他类型。无论其类型如何,arg
都会被分配类型any
和unknown
。
但是,与any
类型不同,类型的变量unknown
不能被分配给另一个类型,如第 7 行和第 8 行所示。any
类型是双向的,而是unknown
单向的。
unknown
在您不知道要传递给函数的值的类型但想摆脱这种情况的情况下,该类型会很有帮助any
。这增加了代码的安全性,因为any
类型可以传播,使您的代码库更容易出错。
strictNullChecks
在 TypeScript 中,null
并且undefined
可以分配给每种类型,这意味着它们在所有类型的域中。
let num: number = 123;
num = null; // Okay
num = undefined; // Okay
通常,这可能会导致意外错误,因为您可以在值为null
或的变量上调用方法undefined
。
interface Person {
hello(): void;
}
const num: number = undefined;
const str: string = null;
const person: Person = null;
person.hello(); // 🔴 Runtime Error!
在严格的空检查模式下,null
不会undefined
自动属于所有类型,因此您不能将它们用于不包含null
or的类型undefined
。这样,您可以在编译时得到一个错误,即Object is possibly 'undefined'
.
TypeScript 和面向对象的编程
课程
就像在 ES6 中一样,可以使用class
关键字来实现类。要创建一个对象,一个类的实例,可以使用new
关键字,它会调用构造函数。请参见下面的示例:
Luna
是 的实例对象Dog
。
class Dog
{
age: number
breed: string
constructor(age: number, breed: string)
{
this.age = age
this.breed = string
}
getRelativeAge(): number
{
return this.age * 7
}
}
let Luna = new Dog(2, 'Labrador')
这种语法等同于在 JavaScript ES5 中使用函数对象。
function Dog(age, breed)
{
this.age = age
this.breed = breed
}
Dog.prototype.getRelativeAge = function() {
return this.age * 7
}
var Spot = new Dog(2, 'Labrador')
继承
既然您知道如何创建对象,那么了解 TypeScript 中的继承就很重要了。继承允许子类从其父类继承某些属性。
例如,您有Animal
, 作为父类。
class Animal
{
age: number
breed: string
constructor(age: number, breed: string)
{
this.age = age
this.breed = breed
}
makeSound_(sound: string): void
{
console.log(sound)
console.log(sound)
console.log(sound)
}
}
然后,您可以创建一个Dog
子类。可以使用super
关键字实现基本的继承,在子类中作为函数调用对应的父函数。
class Dog extends Animal
{
playsFetch: boolean constructor(age: number, breed: string, playsFetch: boolean)
{
super(age, breed) // call parent constructor
this.playsFetch = playsFetch
} makeSound(): void
{
super.makeSound_('woof woof')
} getAgeInHumanYears(): number
{
return this.age * 7 // super.age will throw error
}
}
class Cat extends Animal
{
constructor(age: number, breed: string)
{
super(age, breed)
} makeSound(): void
{
super.makeSound_('meow meow')
}
}
接口
接口在 JavaScript(和 TypeScript)中非常强大,因为它们对运行时的影响为零。TypeScript 允许你声明变量的结构,这给了你更多的权力。
interface Point {
x: number; y: number;
}
declare var test: Point;
TypeScript 中的接口是开放式的,因此其他作者可以在现有的test
变量声明的基础上进行构建。
interface Point {
x: number; y: number;
}
declare var myPoint: Point;
interface Point {
z: number;
}
var myPoint.z; // Allowed
类还可以实现接口,以便它们使用implements
关键字遵循预定义的对象结构。
interface Point {
x: number; y: number;
}
class MyPoint implements Point {
x: number; y: number; // Same as Point
}
由于这个implements
关键字,界面中的任何更改都会产生编译错误,以便您可以轻松更新代码库。
interface Point {
x: number; y: number;
z: number; // New member
}
class MyPoint implements Point { // ERROR : missing member `z`
x: number; y: number;
}
TypeScript 中的类型
TypeScript 最重要的方面之一是从现有的泛型类型创建自定义类型。
联合类型
通常,您可能希望您的代码允许一种以上的数据类型。在接受null
orundefined
值时,这种需求尤其明显。联合类型可以解决这个问题,用|
注解表示。
const hello = (name: string | undefined) => { /* ... */ };
在此示例中,类型name
定义为string | undefined
,这意味着任何类型的变量name
都可以是 astring
或undefined
。
路口类型
交集类型将多种类型合二为一,使得新类型具有组合类型的特征。您可以通过extend
关键字执行此操作,如下所示。
function extend<T, U>(first: T, second: U): T & U {
return { ...first, ...second };
}
const x = extend({ a: "hello" }, { b: 42 });
// x now has both `a` and `b`
const a = x.a;
const b = x.b;
元组类型
与 JavaScript 不同,TypeScript 提供了 Tuple 类型,它允许您使用非统一类型和固定数量的元素来表示数组。下面的示例演示了一个元组。
var nameNumber: [string, number];
// Okay
nameNumber = ['Ben', 12345];
// Error
nameNumber = ['Ben', '12345'];
其他要学习的主题
要成为真正的 TypeScript 大师,还有很多东西要学。看看这个列表,看看未来会发生什么。
- Mapped types
- Discriminated union types
- Decorators
- Function types and return types
- Functional programming in TypeScript
- State machines
- Generic functions
- Other type guards
- 原文作者:知识铺
- 原文链接:https://geek.zshipu.com/post/nextjs/storybooktailwindnextjs/2.4-%E6%8B%93%E5%B1%95%E7%9F%A5%E8%AF%86%E4%BA%86%E8%A7%A3-TypeScript-%E4%B8%AD%E7%9A%84%E9%AB%98%E7%BA%A7%E6%A6%82%E5%BF%B5/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com