暮年|细数这些年被困扰过的 TS 问题


暮年|细数这些年被困扰过的 TS 问题作者: 阿宝哥
转发链接:
前言TypeScript 是一种由微软开发的自由和开源的编程语言 。 它是 JavaScript 的一个超集 , 而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程 。
TypeScript 提供最新的和不断发展的 JavaScript 特性 , 包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性 , 比如异步功能和 Decorators , 以帮助建立健壮的组件 。
小编第一次使用 TypeScript 是在 Angular 2.x 项目中 , 那时候 TypeScript 还没有进入大众的视野 。 然而现在学习 TypeScript 的小伙伴越来越多了 , 本文阿宝哥将分享这些年在学习 TypeScript 过程中 , 曾被困扰过的一些 TS 问题 , 希望本文对学习 TypeScript 的小伙伴能有一些帮助 。
好的 , 下面我们来开始介绍第一个问题 —— 如何在 window 对象上显式设置属性 。
一、如何在 window 对象上显式设置属性对于使用过 JavaScript 的开发者来说 , 对于 window.MyNamespace = window.MyNamespace || {}; 这行代码并不会陌生 。 为了避免开发过程中出现冲突 , 我们一般会为某些功能设置独立的命名空间 。
然而 , 在 TS 中对于 window.MyNamespace = window.MyNamespace || {}; 这行代码 , TS 编译器会提示以下异常信息:
Property 'MyNamespace' does not exist on type 'Window--tt-darkmode-color: #35B378;">Window--tt-darkmode-color: #35B378;">MyNamespace 属性 。 那么如何解决这个问题呢?最简单的方式就是使用类型断言:
(window as any).MyNamespace = {};虽然使用 any 大法可以解决上述问题 , 但更好的方式是扩展 lib.dom.d.ts文件中的 Window 接口来解决上述问题 , 具体方式如下:
declare interface Window {MyNamespace: any;}window.MyNamespace = window.MyNamespace || {};下面我们再来看一下 lib.dom.d.ts 文件中声明的 Window 接口:
/** * A window containing a DOM document; the document property* points to the DOM document loaded in that window.*/interface Window extends EventTarget, AnimationFrameProvider, GlobalEventHandlers,WindowEventHandlers, WindowLocalStorage, WindowOrWorkerGlobalScope, WindowSessionStorage {// 已省略大部分内容readonly devicePixelRatio: number;readonly document: Document;readonly top: Window;readonly window: WindowaddEventListener(type: string, listener: EventListenerOrEventListenerObject,options?: boolean | AddEventListenerOptions): void;removeEventListener(type: K,listener: (this: Window, ev: WindowEventMap[K]) => any,options?: boolean | EventListenerOptions): void;[index: number]: Window;}在上面我们声明了两个相同名称的 Window 接口 , 这时并不会造成冲突 。 TypeScript 会自动进行接口合并 , 即把双方的成员放到一个同名的接口中 。
二、如何为对象动态分配属性在 JavaScript 中 , 我们可以很容易地为对象动态分配属性 , 比如:
let developer = {};developer.name = "semlinker";以上代码在 JavaScript 中可以正常运行 , 但在 TypeScript 中 , 编译器会提示以下异常信息:
Property 'name' does not exist on type '{}'.(2339){} 类型表示一个没有包含成员的对象 , 所以该类型没有包含 name 属性 。 为了解决这个问题 , 我们可以声明一个 LooseObject 类型:


推荐阅读