TypeScript
文章平均质量分 63
TypeScript 在 SAP 产品开发中的应用介绍
汪子熙
Jerry Wang,2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今。Jerry 是 SAP 社区导师,SAP 中国技术大使。在长达16年的 SAP 产品开发生涯里,Jerry 曾经先后参与 SAP Business ByDesign,SAP CRM,SAP Cloud for Customer,SAP S/4HANA,SAP Commerce Cloud(电商云)等标准产品的研发工作。
Jerry 工作中使用 ABAP, Java, JavaScript 和 TypeScript 进行开发, 对包括 SAP UI5 在内的多款 SAP 自研框架有深入的研究。
展开
-
如何使用 TypeScript 的 module augmentation 技术增强 Spartacus Feature Library
Module augmentation 允许我们向现有模块添加新的属性、方法或类型,而无需直接修改原始模块的定义。这对于在扩展功能库时非常有用,因为您通常不希望修改库的核心源代码。相反,您可以创建一个独立的模块来扩展库,并将这些扩展合并到您的应用中,以实现所需的功能。Module augmentation 技术是 TypeScript 中强大的工具之一,它允许我们扩展现有模块的功能,而不必修改原始代码。在 Angular 生态系统中,这种技术在构建功能库和插件时非常有用,可以确保代码的可维护性和可扩展性。原创 2023-10-04 11:55:45 · 37 阅读 · 0 评论 -
关于 HTTP 响应头部字段 X-Cache-Akamai
当你在 Chrome 开发者工具的 Network 面板中看到一个请求的 Response Header 字段的值为head时,这表示 Akamai CDN 已经缓存了该请求的响应头部,但响应体可能没有被缓存。这个机制允许 Akamai CDN 更有效地处理请求,提高网站性能,并且在必要时通过请求源服务器以获取最新内容。原创 2023-07-28 10:14:23 · 127 阅读 · 0 评论 -
TypeScript 对象解构操作符在 Spartacus 实际项目开发中的应用
然后将其转换为一个新的状态对象,并与之前的状态合并返回。如果没有匹配到相应的action类型,将返回当前状态。需要注意的是,这里使用了一些ES6的语法,如对象扩展运算符和解构赋值等,用于更便捷地处理对象和数组。这段代码是一个Angular应用中使用的Reducer函数,用于处理CMS(内容管理系统)导航条目的状态。合并成一个新的对象,并返回新的状态。是一个Angular action的集合,用于触发状态管理器中的特定操作。块,表示收到了加载CMS导航条目成功的动作。为键,对应的组件对象为值。原创 2023-07-27 12:50:06 · 77 阅读 · 0 评论 -
关于 TypeScript 中的联合类型
例如,假设我们有一个函数,它接受一个参数,这个参数可能是一个数字,也可能是一个字符串。联合类型是一种高级的类型定义方式,它允许你定义一个类型为多种类型中的一种。通过使用联合类型,我们可以编写更灵活的代码,同时还能保持强大的类型安全性。联合类型特别有用,因为 TypeScript 会根据联合类型中的所有可能类型来检查我们的代码。不是一个字符串,那么我们知道它必须是一个数字,因此我们可以把它转换为一个字符串,然后获取其长度。,这意味着它可以是一个字符串或者是一个数字。如果是,我们知道它有。原创 2023-07-26 22:24:32 · 112 阅读 · 0 评论 -
关于 Observable 对象调用 subscribe 方法时不传递任何参数值的用法讨论
通过传递相应的回调函数作为参数,我们可以在订阅过程中对 Observable 发出的数据流进行处理和响应。方法被调用时,没有传递任何参数的情况下,这意味着订阅该 Observable 时不处理具体的数据、错误或完成信号。方法时,没有传递任何参数,表示进行空订阅,只是为了触发 Observable 的执行而不处理具体的数据、错误或完成信号。调用,如果 Observable 发出错误或完成信号,它们将被默默地忽略,不会有任何错误处理或完成处理的逻辑执行。方法,可以触发网络请求的执行,而不需要处理响应数据。原创 2023-07-10 22:03:37 · 477 阅读 · 0 评论 -
Rxjs tap 操作符的使用场景介绍
操作符是一个非常有用的工具,它允许我们“查看” Observable 流中的数据,同时不会对数据流产生任何影响。换句话说,它是一种副作用(side effect)操作符,允许我们在不更改主要数据流的情况下执行一些额外的操作,如日志记录、调试或其他副作用。在这个例子中,我们创建了一个发出 1、2 和 3 的 Observable,然后使用。操作符的使用场景之前,让我们先了解一下它的基本用法。操作符在每个值发出时打印出来。操作符的常见使用场景有哪些呢?原创 2023-07-10 22:00:57 · 417 阅读 · 0 评论 -
什么是 Rxjs Observable subscribe 方法的副作用
这就是为什么说 Observable 的 subscribe 方法有副作用(side effects):因为当开发人员订阅(subscribe)一个 Observable 时,开发人员实际上是在定义当 Observable 发射数据时应该执行什么操作,这些操作可能会改变程序的状态,即产生副作用。因为 Observable 可能会发射多次数据,所以开发人员订阅的操作可能会被执行多次,如果这些操作有副作用,那么就可能会对程序的状态产生重复的、可能不可预测的改变。这些操作可能会改变程序的状态,产生副作用。原创 2023-07-10 21:59:01 · 302 阅读 · 0 评论 -
Angular Component 里使用 const 和 readonly 修饰的属性有什么区别
这两个关键字的目的都是为了确保数据的不变性,但它们在实现和用法上有很大的区别。在本文中,我们将详细讨论这两者之间的区别,并在不少于 2800 字的篇幅内进行深入分析。这意味着,在 Angular 组件中,我们需要在类外部声明。关键字用于定义一个常量,它的值在声明时必须赋值,并且在后续代码中无法修改。属性可以在声明时赋值,也可以在构造函数中赋值。因此,在组件类中,我们需要在类外部声明。关键字用于修饰类的成员属性,表示该属性的值在实例化后不可修改。关键字专门用于修饰类的成员属性,可以直接在组件类中使用。原创 2023-07-02 09:38:17 · 217 阅读 · 0 评论 -
一个前端开发工程师的天猫精灵评测报告
虽然从普通用户眼中,使用语音向天猫精灵发起指令,然后收到后者的语音回复,这个流程似乎很简单,但背后实际上有着人工智能中 ASR(语音识别)、NLP(自然语言处理)、TTS(语音合成)等自然语言处理技术的参与和整合。我们先来看一个典型的用户通过语音同天猫精灵交互的流程图。用户用语音唤醒天猫精灵,后者接收到用户语音,上传到智能应用平台。平台使用 ASR(音频转文字)和 NLP(自然语言处理)技术,智能解析出用户发出语音包含的意图(通俗的说,即用户当前期望天猫精灵完成什么样的操作)。平台会自动将当前原创 2022-07-22 10:39:23 · 889 阅读 · 0 评论 -
rxjs Observable 设计原理背后的 Pull 和 Push 思路
Observables 顾名思义,是可以被观察的事务。在 Rxjs 的上下文里,Observable 会随着时间的推移,在某个时间点产生数据。Observables 可以:不停地(永远)产生值,比如 interval 操作符。可以一次性生产价值,然后进入 complete 状态。可能会产生错误,然后进入 complete 状态。Observable 是一种异步事件的实现利器,例如单个操作(HTTP 请求)或多个可重复的操作(例如光标移动或按键)。响应式编程(Reactive Programm原创 2022-07-22 10:27:14 · 177 阅读 · 0 评论 -
在 NgModule 里通过依赖注入的方式注册服务实例
首先,我们现在可以拥有两个具有完全相同类名的providers,Angular在解析正确的服务时不会有任何问题。其次,我们还可以使用不同的提供者覆盖现有提供者,同时保持令牌相同。对象中的provide属性是我们正在注册的提供者的令牌。现在假设有一个新的需求,需要将我们的登录身份验证方式,更改为一个使用Facebook登录用户的库。上面的例子用不同的值替换了useClass属性。这样,我们可以在我们的应用程序中的任何地方使用AuthService-而无需进行进一步的更改。...原创 2022-07-18 19:15:50 · 272 阅读 · 0 评论 -
Angular InjectionToken APP_INITIALIZER 的实现方法介绍
APP_INITIALIZER 是 InjectionToken的一个实例。它是 Angular 提供的内建注入令牌。Angular会在应用加载时执行这个令牌提供的函数。如果函数返回promise,那么angular会一直等待,直到promise被解析。这将使它成为在应用程序初始化之前执行一些初始化逻辑的理想位置。Angular 注入器使用 DI 令牌来定位 Angular providers 中的依赖项。我们使用令牌在提供者中注册依赖项:上面代码里的 ,可以是一个 type,一个字符串,或者是 Inje原创 2022-07-11 16:11:34 · 325 阅读 · 0 评论 -
SAP 电商云 Spartacus UI Site Context 模块里 Providers 组件的实现明细
index.ts 里只有两份 export:是一些参数常量。context-service-map.ts (ContextServiceMap)ContextServiceMap 是一个 map 结构,key 是字符串,value 是这种 site context 对应的 SiteContext Facade 类?比如我们之前在 文件夹里讨论过的:serviceMapFactory工厂函数,负责提供 ContextServiceMap 的实现?什么时候 ContextServiceMap 的实原创 2022-07-11 15:54:52 · 235 阅读 · 0 评论 -
如何使用 Angular 服务器端渲染的 Transfer State Service
假设我们使用 Angular Universal 开发一个服务器端渲染的 Angular 应用,这个应用会消费一个第三方的 Restful API.上述场景分为下列六个步骤:用户向部署了 Angular 服务器端应用的 Node.js 服务器发起页面请求Node.js 调用第三方 Restful API,第三方 Restful API 返回结果,这个结果被用于渲染最后的页面服务器端渲染的页面,返回给浏览器Angular 在浏览器中引导,并再次调用 Restful API原创 2022-06-24 16:27:20 · 312 阅读 · 0 评论 -
关于 JavaScript 事件循环 Event Loop 的一些理解
浏览器 JavaScript 执行流程以及在 Node.js 中都是基于事件循环的。了解事件循环的工作原理对于正确编写健壮和高性能的 JavaScript 代码非常重要。本文首先介绍有关事物如何工作的理论细节,然后介绍这些知识的实际应用。事件循环遵循下面的处理范式:任务被设置——引擎处理它们——然后等待更多任务(在睡眠和消耗接近于零的 CPU 事件)。如果在 JavaScript 执行引擎忙时又有新任务达到,这些新任务会被排队,形成一个队列,即所谓的 (v8 术语)。例如,当引擎忙于执行脚本时,用户可能会移原创 2022-06-14 09:47:23 · 226 阅读 · 0 评论 -
rxjs 里 Skip 操作符的一个使用场景
skip 操作符允许我们忽略源的前 x 个排放。 当我们有一个始终在 subscription 上发出希望忽略的某些值的可观察对象时,就可以使用这个操作符。比如 Observable emit 的前几个值并不是我们感兴趣的值,另一种情况是我们订阅了 Replay 或 BehaviorSubject,并且不需要对初始值进行操作,而只关心初始值之后的数据 emit. 这种情况下,skip 操作符非常有用。有时候我们可以通过使用带有索引的 filter 操作符来达到和使用 skip 同样的效果:filter原创 2022-05-14 21:54:21 · 299 阅读 · 0 评论 -
Content Security Policy 学习笔记之二:default-src 指令的使用方式
我们定义了这样一条 CSP 策略:Content-Security-Policy: script-src ‘self’ https://apis.google.comscript-src 是一个指令,用于控制特定页面的一组与脚本相关的权限。 我们将 self 指定为一个有效的脚本来源,并将 https://apis.google.com 指定为另一个。 浏览器尽职尽责地通过 HTTPS 从 apis.google.com 以及当前页面的来源下载并执行 JavaScript。定义此策略后,当浏览器从原创 2022-05-14 21:40:38 · 2770 阅读 · 0 评论 -
rxjs 里 CombineLatest 操作符的一个使用场景
一个具体的例子:combineLatest([ data$.pipe(startWith(null)), loading$,]).pipe( takeWhile(([data, loading]) => !data || loading, true), map(([data, loading]) => loading ? null : data), skip(1), distinctUntilChanged(),);我们在这里使用巧妙的 takeWhile 函数原创 2022-05-10 09:33:49 · 455 阅读 · 0 评论 -
SAP 电商云 Spartacus UI ActiveCartService 的 isStable API 里的 EMPTY 操作符
isStable API 源代码如下:return this.activeCartId$.pipe( switchMap((cartId) => this.multiCartService.isStable(cartId)), debounce((state) => (state ? timer(0) : EMPTY)), distinctUntilChanged() );EMPTY 操作符:直接发送 complete 事件。看一个简单的例原创 2022-05-09 09:43:27 · 265 阅读 · 1 评论 -
TypeScript 里的 Reference Type 和 Triple-Slash Directives
SAP Spartacus 是一个 TypeScript 应用,在有些文件开头,发现了这样的定义:// '@sapui5/ts-types-esm' package contains types for sap modules, e.g. 'sap/ui/core/Core'/// <reference types="@sapui5/ts-types-esm" />对第 31 行的代码按住 Ctrl 再单击鼠标左键:直接跳转到了 sap.ui.core.d.ts 文件内部:///原创 2022-05-08 09:50:15 · 437 阅读 · 0 评论 -
什么是 constructor signature in interface
接口中的 constructor signature 不能在类中实现; 它们仅用于定义定义 newable 的现有 JS API. 下面是一个例子:interface ComesFromString { name: string;}意思是这个接口代表一个可以使用 `new` 操作符操作的对象。返回的类型是 ComesFromStringinterface StringConstructable { new(n: string): ComesFromString;}class原创 2022-03-25 10:05:16 · 540 阅读 · 2 评论 -
SAP UI5 的 TypeScript 实践
TypeScript 是 JavaScript 的超集,它为语言添加了可选的静态类型。 它带有一个编译器,可以将 TypeScript 代码转换为 JavaScript,并在 JavaScript 运行的任何地方运行它,浏览器,NodeJS 等等。 最大的变化是 TypeScript 自带了 Types。同时,这使得开发像您在 JavaScript 中可能习惯的通用代码变得更加困难,因为它是无类型的。TypeScript 的目标是在我们的 IDE 中提供更好的集成,以帮助我们更早地发现错误。TypeScr原创 2022-01-30 09:52:17 · 790 阅读 · 0 评论 -
通过 SAP UI5 的 TypeScript 开发环境,来学习什么是 DefinitelyTyped
我们看个具体的例子。下面这个使用 TypeScript 编写的 SAP UI5 Component:import UIComponent from "sap/ui/core/UIComponent";/** * @namespace ui5.typescript.helloworld */export default class Component extends UIComponent { public multiply(x : number, y : number) : numb原创 2022-01-28 10:05:29 · 727 阅读 · 0 评论 -
使用 TypeScript 编写 SAP UI5 应用的准备工作
新建一个文件夹 ui5-ts, 执行命令行 npm init -y 初始化:新建一个 src 文件夹,里面存放一个 Component.ts 文件,源代码如下:import UIComponent from "sap/ui/core/UIComponent";/** * @namespace ui5.typescript.helloworld */export default class Component extends UIComponent { public multiply原创 2022-01-27 09:41:58 · 469 阅读 · 0 评论 -
rxjs 操作符 pairwise 的一个例子
Groups pairs of consecutive emissions together and emits them as an array of two values.pairwise 将连续的发射出的值进行分组并配对,然后以数组的数据结构进行发射。pairwise 返回的数据类型如下:返回一个新的 OperatorFunction,这是一个函数,该函数返回一个新的 Observable,以数组的结构包裹了源 Observable 发射的值。OperatorFunction<T, .原创 2022-01-14 16:36:51 · 464 阅读 · 0 评论 -
debounceTime 和 throttleTime 的弹珠图
debounceTime:测试代码import { concat, debounceTime, filter, interval, mapTo, of, take, throttleTime,} from 'rxjs';const a = of(1);const b = of(2);const c = concat(a, b);c.subscribe((data) => console.log(data));const a1$ = interval原创 2022-01-05 15:12:48 · 438 阅读 · 0 评论 -
rxjs ThrottleTime 和 debounceTime 的操作符区别
throttleTime 的作⽤是限制在 duration 时间范围内,从上游传递给下游数据的个数;debounceTime 的作⽤是让传递给下游的数据间隔不能⼩于给定的时间 dueTime。一旦把下列代码拷贝到 StackBlitz 里,就报错:import { interval, throttleTime } from 'rxjs';import 'rxjs/add/observable/interval';import 'rxjs/add/operator/throttleTime';.原创 2022-01-05 14:29:55 · 1319 阅读 · 1 评论 -
Cypress 的条件测试
条件测试用下列的编程范式可以清晰表示出来:If X, then Y, else Z如今,现代 JavaScript 应用程序是高度动态和可变的。 它们的状态和 DOM 在一段时间内不断变化。条件测试的问题在于它只能在状态稳定后才能使用。 在现代应用程序中,知道状态何时稳定通常是不可能的。对人类而言——如果从现在起 10 毫秒或 100 毫秒发生变化,我们甚至可能不会注意到这种变化并假设状态总是相同的。对于机器人来说——即使是 10 毫秒也代表着数十亿+ 的时钟周期。 时间尺度的差异令人难以置信原创 2021-12-30 15:09:59 · 732 阅读 · 0 评论 -
Cypress 里的 Flaky test 管理
鼠标 hover 上去,看到提示信息:This test both passed and failed when retried within a run何谓 Flaky test?Cypress 官网有如下定义:当一个测试可以在多次重试尝试中通过和失败而没有任何代码更改时,它被认为是不稳定的。例如,执行了一个测试并失败,然后再次执行该测试,代码没有任何更改,但这次它通过了。当之前测试过的代码测试失败时,这是一个强烈的信号,表明代码出现了新的错误。 之前,测试通过,代码正确; 现在测试失败并原创 2021-12-28 22:04:13 · 358 阅读 · 0 评论 -
关于 TypeScript 联合类型 union type 赋值的一个错误消息
今天我做开发时遇到如下的 TypeScript 错误:Type ‘Observable<boolean | undefined>’ is not assignable to type ‘Observable’.Type ‘boolean | undefined’ is not assignable to type ‘boolean’.Type ‘undefined’ is not assignable to type ‘boolean’.ts(2322)原因是参与 combine原创 2021-12-08 15:06:06 · 691 阅读 · 0 评论 -
TypeScript Partial 使用的一个小技巧
TypeScript 提供了一些工具性质的类型定义来方便开发人员进行一些通用的类型定义。Partial 是其中之一。看个例子:interface Todo { title: string; description: string;}const todo1 = { title: 'organize desk', description: 'clear clutter',};我们将如何编写一个方法来获取我们的 Todo 实例并使用来自另一个 Todo 的值更新它?原创 2021-12-08 11:42:22 · 347 阅读 · 0 评论 -
什么是 TypeScript 的 Module Augmentation
在进入模块扩充之前,让我们看看一些 TypeScript 合并原则,这些原则将随着我们的进步而变得有用。TypeScript 支持创建同名的 class 和 interface:class Food { cheese: string;}interface Food { bacon: string;}const food = new Food();food.bacon = "nice bacon";food.cheese = "sweet cheese";console.lo原创 2021-12-01 16:47:37 · 813 阅读 · 0 评论 -
从一个实际的例子出发,理解什么是 Rxjs 的 defer 函数
我们在开发复杂的 Angular 应用时,经常会使用到 Rxjs 的 defer 函数,例如:创建一个 Observable,在订阅时调用 Observable 工厂为每个新的 Observer 创建一个 Observable 对象。该函数接收一个输入参数,类型为一个工厂函数。输出为一个 Observable 对象,一旦被订阅时,其绑定的工厂函数会被调用。defer 的实质是延迟创建机制,即只有在返回的 Observable被订阅时,才开始创建 Observable 对象。defer 允许你只在原创 2021-11-27 22:54:50 · 666 阅读 · 0 评论 -
JavaScript 里三个点 ... 的用法
Three dots ( … ) in JavaScriptRest Parameters使用 rest 参数,我们可以将任意数量的参数收集到一个数组中,然后用它们做我们想做的事情。 引入了其余参数以减少由参数引起的样板代码。function myFunc(a, b, ...args) { console.log(a); // 22 console.log(b); // 98 console.log(args); // [43, 3, 26]};myFunc(22, 98, 43, 3, 2原创 2021-10-16 16:15:01 · 1357 阅读 · 0 评论 -
关于 TypeScript 内 constructor signature 的一些失败尝试
interface ArrayContaining { //new (sample: any[]): any; jasmineToString(): string; }class Jerry{ jasmineToString = () => '1'; constructor(private name:string){ console.log('name: ', this.name); }}const b:ArrayCon原创 2021-09-29 21:15:45 · 283 阅读 · 0 评论 -
TypeScript constructor signature 类型的变量赋值方式
看这段代码:interface ArrayContaining { new (sample: string): any;}试图给一个类型为 ArrayContaining 的变量赋值,下列这样赋值行不通:const a: ArrayContaining = () => 1;遇到错误消息:Type ‘() => number’ is not assignable to type ‘ArrayContaining’.Type ‘() => number’原创 2021-09-29 12:37:07 · 411 阅读 · 0 评论 -
如何理解 new (...args: any[]) => any
关于javascript:如何开始理解类型…args:any [])=> any如何理解下面这段代码里的 new 操作?/** * Checks if the value is an instance of the specified object. */isInstance(object: any, targetTypeConstructor: new (...args: any[]) => any) { return targetTypeConstructor原创 2021-09-28 11:38:03 · 1657 阅读 · 0 评论 -
NgRx Selector 的 Memoization 特性学习笔记
在计算机编程领域中,memoization 或 memoisation 是一种优化技术,主要用于通过存储昂贵的函数调用的结果并在再次出现相同的输入时返回缓存的结果来加速计算机程序。Memoization 也已用于其他上下文(以及速度增益以外的目的),例如在简单的相互递归下降解析中。尽管与缓存有关,但记忆化是指此优化的特定情况,将其与缓存或页面替换等缓存形式区分开来。在某些逻辑编程语言的上下文中,记忆化也称为 Tabling.记忆功能“记住”与某些特定输入集相对应的结果。使用记住输入的后续调用返回记住的结原创 2021-09-15 16:36:14 · 288 阅读 · 0 评论 -
RxJs SwitchMapTo 操作符之移花接木
将每个源值投影到同一个 Observable,该 Observable 在输出 Observable 中使用 switchMap 多次展平。输入一个 Observable,输出一个 function Operator. 实际是一个函数,每次在源 Observable 上发出值时,该函数都会返回一个 新的 Observable.该函数从给定的 innerObservable 发出项目,并且仅从最近投影的内部 Observable 中获取值。看个例子:import { EMPTY, range } fr原创 2021-09-15 16:02:41 · 305 阅读 · 0 评论 -
Rxjs 的一些学习笔记
源自观察者-发布者设计模式:观察者注册于 Subject 上,每当 subject 状态发生变化时,通知观察者。RxJs 里的 Observable 就是 Subject:管道:连接 Observable 的同时,增添额外的逻辑:冷热 Observable 的区别:Cold Observable,仅当被订阅时,才通过内部生产者生产数据Hot Observable,具有外部生产者,不管被订阅与否,都能够自主生产数据,比如基于 HTML Event listener 的 Observable原创 2021-09-12 17:34:55 · 260 阅读 · 0 评论