• [技术干货] Promise.allSettled 函数的用法详解
    Promise.allSettled 函数的用法详解及使用场景说明用法详解Promise.allSettled 是 JavaScript ES2020 (ES11) 中引入的一个静态方法,用于处理多个 Promise,并在所有 Promise 都已经成功(fulfilled)或失败(rejected)后,返回一个包含每个 Promise 结果的数组。语法:Promise.allSettled(iterable)iterable:一个可迭代对象(如数组),其中包含多个 Promise。返回值:返回一个新的 Promise,该 Promise 在所有给定的 Promise 都已经 fulfilled 或 rejected 后完成。返回的 Promise 解析为一个数组,数组中的每个元素都是一个对象,表示对应 Promise 的结果。如果 Promise 成功(fulfilled),则对象包含 status: 'fulfilled' 和 value 属性,其中 value 是 Promise 的解决值。如果 Promise 失败(rejected),则对象包含 status: 'rejected' 和 reason 属性,其中 reason 是 Promise 的拒绝原因。示例代码:const promise1 = Promise.resolve(42); const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'error')); const promise3 = Promise.resolve('Hello World'); Promise.allSettled([promise1, promise2, promise3]).then((results) => { results.forEach((result) => { if (result.status === 'fulfilled') { console.log(`Fulfilled with value: ${result.value}`); } else { console.log(`Rejected with reason: ${result.reason}`); } }); });在这个例子中,promise1 和 promise3 成功解决,而 promise2 被拒绝。Promise.allSettled() 返回的 Promise 将解析为一个包含这三个 Promise 结果的数组。输出结果将显示 promise1 和 promise3 的成功值,以及 promise2 的拒绝原因。使用场景说明并行任务处理:当需要并行执行多个异步任务,并且需要在所有任务都完成后(无论成功还是失败)进行汇总或处理时,可以使用 Promise.allSettled()。例如,同时从多个 API 获取数据,并在所有数据都获取后进行汇总分析。容错处理:在执行多个可能失败的异步操作时,如果希望即使某些操作失败也能继续处理其他操作的结果,可以使用 Promise.allSettled()。例如,从多个数据源获取数据,即使某些数据源返回错误,也可以继续处理其他数据源返回的数据。日志记录:当需要记录多个异步操作的结果,无论它们是否成功时,可以使用 Promise.allSettled()。例如,在执行一系列异步操作时,记录每个操作的成功或失败状态以及相关的结果或错误信息。依赖多个异步条件的决策:在某些情况下,可能需要根据多个异步操作的结果来做出决策,而这些操作中的某些可能会失败。使用 Promise.allSettled() 可以确保在所有操作都完成后才进行决策,同时考虑到每个操作的成功或失败情况。总的来说,Promise.allSettled() 是一个有用的工具,用于处理多个 Promise 并在所有 Promise 都完成后(无论成功还是失败)获取它们的结果。它特别适用于需要并行任务处理、容错处理、日志记录以及依赖多个异步条件的决策等场景。
  • [技术干货] Typescript Promise.any 函数的用法详解
    Promise.any 函数的用法详解及使用场景说明用法详解Promise.any 是 JavaScript ES2021 (ES12) 中引入的一个静态方法,它用于处理多个 Promise,并返回第一个成功解决(fulfilled)的 Promise 的结果。语法:Promise.any(iterable)iterable:一个可迭代对象(如数组),其中包含多个 Promise。返回值:返回一个新的 Promise。如果至少有一个 Promise 成功解决(fulfilled),则返回该 Promise 的解决值。如果所有的 Promise 都被拒绝(rejected),则返回一个拒绝的 Promise,并带有一个 AggregateError,其中包含所有被拒绝的错误。示例代码:const promise1 = Promise.reject('Error 1'); const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'Success 2')); const promise3 = new Promise((resolve) => setTimeout(resolve, 200, 'Success 3')); Promise.any([promise1, promise2, promise3]).then((value) => { console.log(value); // "Success 2" }).catch((error) => { console.log(error); });在这个例子中,promise2 是第一个成功解决的 Promise,所以 Promise.any() 返回 promise2 的解决值 “Success 2”。如果所有的 Promise 都被拒绝,Promise.any() 将返回一个包含所有拒绝原因的 AggregateError。const promise1 = Promise.reject('Error 1'); const promise2 = Promise.reject('Error 2'); const promise3 = Promise.reject('Error 3'); Promise.any([promise1, promise2, promise3]).then((value) => { console.log(value); }).catch((error) => { console.log(error); // AggregateError: All promises were rejected });使用场景说明从最快的服务器检索资源:当需要从多个服务器获取资源,并且只关心哪个服务器响应最快时,可以使用 Promise.any()。例如,一个网站可能有多个服务器,用户访问时,可以使用 Promise.any() 从响应最快的服务器接收数据。容错处理:在执行多个可能失败的异步操作时,如果只需要其中一个成功的结果,可以使用 Promise.any()。例如,从多个数据源获取数据,只要有一个数据源成功返回数据,就可以使用这些数据。超时与重试机制:在需要实现超时与重试机制的异步操作中,Promise.any() 可以与设置超时的 Promise 结合使用。例如,发送一个网络请求,并同时设置一个超时 Promise,如果请求在超时前完成,则返回请求的结果;如果请求超时,则返回超时错误。并行任务处理:当需要并行处理多个任务,并且只需要其中一个任务成功完成时,可以使用 Promise.any()。例如,同时执行多个计算任务,只要有一个任务成功计算出结果,就可以使用该结果。总的来说,Promise.any() 是一个有用的工具,用于处理多个 Promise 并获取第一个成功的结果。它特别适用于需要从多个异步操作中获取第一个成功结果,或者实现容错处理和超时与重试机制的场景。
  • [技术干货] Typescript Promise.race 的具体用法
    Promise.race函数的用法详解Promise.race 是 JavaScript 中 Promise 对象的一个静态方法,用于处理多个 Promise 实例的竞赛,返回一个新的 Promise 实例。这个新的 Promise 实例的状态由第一个完成(无论是成功还是失败)的 Promise 实例决定。用法Promise.race(iterable)iterable:一个可迭代对象,通常是一个数组,其中包含多个 Promise 实例或类似 Promise 的对象(即具有 then 方法的对象)。返回值返回一个新的 Promise 实例。如果第一个完成的 Promise 实例是成功的(即状态变为 fulfilled),则新的 Promise 实例也会成功,其值与第一个完成的 Promise 实例的值相同。如果第一个完成的 Promise 实例是失败的(即状态变为 rejected),则新的 Promise 实例也会失败,其原因与第一个完成的 Promise 实例的原因相同。示例代码let promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise1 resolved'); }, 1000); }); let promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Promise2 resolved'); }, 2000); }); Promise.race([promise1, promise2]).then((result) => { console.log(result); // "Promise1 resolved",因为 promise1 先完成 });在这个示例中,promise1 在 1000 毫秒后完成,而 promise2 在 2000 毫秒后完成。因此,Promise.race 返回的新的 Promise 实例会在 1000 毫秒后被解决,其值为 "Promise1 resolved"。使用场景说明1. 请求超时处理在网络请求中,有时需要设置一个超时时间,以避免请求过长时间无响应。可以使用 Promise.race 来实现这一点,将一个正常的请求 Promise 和一个设置超时的 Promise 进行竞赛,哪个先完成就以哪个的结果为准。如果超时 Promise 先完成(即请求超时),则可以拒绝新的 Promise 实例,从而处理超时错误。2. 快速响应场景当有多个异步操作,但只需要最快完成的那一个的结果时,可以使用 Promise.race。例如,在多个网络请求中,只需要最快返回的结果来更新页面状态或显示加载动画,此时可以使用 Promise.race 来获取最快完成的那个请求的结果。3. 取消操作在某些情况下,可能需要取消某个异步操作。例如,下载一个大文件时,用户可能决定取消下载。可以使用 Promise.race 来实现这一点,将一个下载操作的 Promise 和一个取消操作的 Promise 进行竞赛。如果用户点击取消按钮,则取消操作的 Promise 会先完成,从而拒绝新的 Promise 实例,实现取消下载的效果。总的来说,Promise.race 提供了一种优雅的方式来处理多个 Promise 实例的竞赛,根据第一个完成(成功或失败)的 Promise 实例的结果来决定新的 Promise 实例的状态。在需要快速响应、请求超时处理或取消操作等场景中,Promise.race 都是非常有用的工具。
  • [技术干货] Typescript Promise.all 函数用法详解
    Promise.all 函数的用法详解Promise.all 是 JavaScript 中 Promise 对象的一个静态方法,用于将多个 Promise 实例包装成一个新的 Promise 实例。这个新的 Promise 实例会在所有传入的 Promise 实例都成功完成时才会成功,否则一旦有任何一个 Promise 实例失败,新的 Promise 实例就会立即失败。用法Promise.all(iterable)iterable:一个可迭代对象,如数组,其中包含多个 Promise 实例或类似 Promise 的对象(具有 then 方法的对象)。返回值返回一个新的 Promise 实例。如果所有传入的 Promise 实例都成功完成,新的 Promise 实例会成功完成,并将所有 Promise 的返回值作为数组传递给 then 方法的回调函数。如果任意一个传入的 Promise 实例失败,新的 Promise 实例会立即失败,并将第一个被拒绝的 Promise 的错误信息传递给 catch 方法的回调函数。示例代码let promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve({"id": "1001", "sex": "男"}); }, 2000); }); let promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve({"id": "1001", "age": 30}); }, 1000); }); Promise.all([promise1, promise2]).then(res => { console.log(res); // [{ "id": "1001", "sex": "男"}, { "id": "1001", "age": 30}] });使用场景说明1. 并发数据获取当需要从多个 API 或数据源同时获取数据时,可以使用 Promise.all。例如,一个页面可能需要同时从后端获取用户信息、订单信息和商品信息,此时可以将这三个异步请求包装成 Promise 对象,并使用 Promise.all 来等待它们全部完成。这样做的好处是可以并行处理这些请求,提高数据加载的效率。2. 依赖关系处理虽然 Promise.all 本身并不直接处理依赖关系,但在某些情况下,可以利用它来等待多个相互依赖的异步操作完成。例如,一个操作可能依赖于另外两个异步操作的结果,此时可以使用 Promise.all 来等待这两个操作完成后,再进行后续的操作。不过,在这种情况下,更推荐使用 async/await 语法来清晰地表示异步操作的顺序和依赖关系。3. 错误处理Promise.all 还用于处理多个异步操作中的错误。当同时执行多个异步操作,并且希望一旦有任何一个操作失败就立即捕获错误时,Promise.all 提供了便捷的机制。它会返回一个新的 Promise 对象,该对象在所有传入的 Promise 对象都成功完成时才会成功,否则一旦有任何一个 Promise 对象失败,新的 Promise 对象就会立即失败,并将第一个失败的 Promise 对象的原因作为失败原因。4. 资源并行加载在前端开发中,经常需要加载各种资源,如图片、CSS 文件、JavaScript 脚本等。使用 Promise.all 可以并行地加载这些资源,并在所有资源都加载完成后进行后续的操作,如渲染页面或执行某些初始化代码。总的来说,Promise.all 是处理多个并发异步操作的强大工具,它提高了代码的可读性和可维护性,同时也提高了应用程序的性能和响应速度。在前端开发中,合理地使用 Promise.all 可以帮助开发者更好地管理和协调各种异步操作,从而构建出更加高效和稳定的 Web 应用。
  • [技术干货] Typescript Promise常用函数
    Promise 是 JavaScript(包括 TypeScript)中一种用于处理异步操作的对象,它提供了一系列函数来管理异步流程。以下是 Promise 支持的主要函数:1. Promise 构造函数作用:创建一个新的 Promise 实例。参数:一个执行器函数,该函数接受两个参数:resolve 和 reject。resolve 用于将 Promise 的状态从 pending 变为 fulfilled,而 reject 用于将状态从 pending 变为 rejected。2. then 函数作用:为 Promise 实例添加状态改变时的回调函数。参数:两个可选的回调函数,第一个用于处理 fulfilled 状态,第二个(可选)用于处理 rejected 状态。如果 Promise 成功完成,则调用第一个回调函数,并将 Promise 的返回值作为参数传递给它;如果 Promise 失败,则调用第二个回调函数,并将错误信息作为参数传递给它。3. catch 函数作用:为 Promise 实例添加错误处理回调函数。参数:一个错误处理回调函数,当 Promise 被拒绝时调用,并将错误信息作为参数传递给它。catch 函数相当于调用 then 函数的第二个参数(错误处理回调)。4. finally 函数作用:为 Promise 实例添加无论成功还是失败都会执行的回调函数。参数:一个不接受任何参数的回调函数。无论 Promise 的最终状态是 fulfilled 还是 rejected,finally 函数中的回调函数都会被调用。5. Promise.all 函数作用:将多个 Promise 实例包装成一个新的 Promise 实例。参数:一个包含多个 Promise 实例的数组。行为:只有当所有传入的 Promise 实例都成功完成时,新的 Promise 实例才会成功完成,并将所有 Promise 的返回值作为数组传递给 then 函数。如果任意一个 Promise 实例失败,则新的 Promise 实例会立即失败,并将第一个被拒绝的 Promise 的错误信息传递给 catch 函数。6. Promise.race 函数作用:与 Promise.all 类似,但行为有所不同。参数:一个包含多个 Promise 实例的数组。行为:只要有一个 Promise 实例成功完成或失败,新的 Promise 实例就会采用该 Promise 的状态,并将它的返回值或错误信息传递给后续的 then 或 catch 函数。7. Promise.any 函数作用:接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。行为:只要参数实例中有一个变成 fulfilled 状态,包装实例就会变成 fulfilled 状态;如果所有参数实例都变成 rejected 状态,包装实例就会变成 rejected 状态。与 Promise.race 不同的是,Promise.any 不会因为某个 Promise 变成 rejected 状态而结束,必须等到所有参数 Promise 变成 rejected 状态才会结束。8. Promise.resolve 和 Promise.reject 函数作用:分别用于创建一个已解决(fulfilled)或已拒绝(rejected)的 Promise 实例。参数:Promise.resolve 接受一个值作为参数,并返回一个以该值解决的 Promise 实例。Promise.reject 接受一个错误原因作为参数,并返回一个以该原因拒绝的 Promise 实例。9. Promise.allSettled 函数作用:等待所有给定的 Promise 实例解决(fulfilled)或拒绝(rejected),并返回一个在所有 Promise 实例都已经结束后的新 Promise 实例。参数:一个包含多个 Promise 实例的数组。返回值:新的 Promise 实例在解决时返回一个数组,数组中的每个元素都是描述对应 Promise 实例状态的对象。这些函数共同构成了 Promise 的核心功能,使得开发者能够更优雅地处理异步操作,避免回调地狱,并提高代码的可读性和可维护性。
  • [技术干货] Typescript Promise的基础用法
    TypeScript 中 Promise 的用法在现代前端开发中,异步编程是不可避免的一部分。JavaScript 提供了多种处理异步操作的方法,其中 Promise 是一种非常强大且常用的工具。TypeScript 作为 JavaScript 的超集,不仅继承了 Promise 的所有功能,还通过类型系统增强了其可读性和安全性。本文将详细介绍在 TypeScript 中如何使用 Promise。什么是 Promise?Promise 是一个代表异步操作最终完成或失败的对象。它有三种状态:Pending(等待):初始状态,既不是成功,也不是失败状态。Fulfilled(已完成):意味着操作成功完成。Rejected(已拒绝):意味着操作失败。Promise 提供了 .then() 和 .catch() 方法来处理成功和失败的情况,以及 .finally() 方法来处理无论成功还是失败都需要执行的逻辑。基本用法首先,让我们看一个简单的 Promise 示例:function fetchData(): Promise<string> { return new Promise((resolve, reject) => { setTimeout(() => { const success = true; // 模拟一个成功或失败的条件 if (success) { resolve("数据获取成功!"); } else { reject("数据获取失败!"); } }, 1000); }); } fetchData() .then(data => { console.log(data); // "数据获取成功!" }) .catch(error => { console.error(error); // "数据获取失败!" });在这个例子中,fetchData 函数返回一个 Promise,它在一秒钟后模拟成功或失败。TypeScript 中的类型安全TypeScript 的强大之处在于类型系统。使用 Promise 时,可以明确指定其解析值(fulfilled value)和拒绝原因(rejection reason)的类型。function fetchUserData(): Promise<{ name: string; age: number }> { return new Promise((resolve, reject) => { // 模拟异步操作 setTimeout(() => { const user = { name: "张三", age: 30 }; resolve(user); }, 1000); }); } fetchUserData() .then(user => { console.log(`姓名: ${user.name}, 年龄: ${user.age}`); }) .catch(error => { console.error("获取用户数据失败:", error); });在这个例子中,fetchUserData 函数返回一个解析值为 { name: string; age: number } 类型的 Promise。链式调用和错误处理Promise 支持链式调用,每个 .then() 都可以返回一个新的 Promise,从而可以串联多个异步操作。function fetchUser(): Promise<string> { return Promise.resolve("张三"); } function getUserAge(userName: string): Promise<number> { return new Promise(resolve => { // 模拟根据用户名获取年龄 setTimeout(() => { resolve(userName === "张三" ? 30 : 25); }, 1000); }); } fetchUser() .then(userName => { console.log(`用户名: ${userName}`); return getUserAge(userName); }) .then(age => { console.log(`年龄: ${age}`); }) .catch(error => { console.error("发生错误:", error); });在上面的例子中,fetchUser 返回用户名,然后 getUserAge 根据用户名返回年龄。通过链式调用,我们可以依次执行这些异步操作。使用 async/await虽然 Promise 提供了强大的功能,但处理多个异步操作时,代码可能会变得复杂且难以阅读。async 和 await 语法是对 Promise 的一个语法糖,可以使异步代码看起来更像是同步代码。async function getUserInfo(): Promise<void> { try { const userName: string = await fetchUser(); console.log(`用户名: ${userName}`); const age: number = await getUserAge(userName); console.log(`年龄: ${age}`); } catch (error) { console.error("发生错误:", error); } } getUserInfo();在这个例子中,async 函数 getUserInfo 使用 await 等待 Promise 的结果,并且使用 try...catch 块来处理错误。总结Promise 是处理异步操作的强大工具,TypeScript 通过类型系统增强了其可读性和安全性。通过理解 Promise 的基本用法、类型安全、链式调用、错误处理以及 async/await 语法,你可以更加高效地编写异步代码。希望这篇文章能帮助你更好地掌握 TypeScript 中的 Promise。
  • [问题求助] vercel注册时遇到问题
    使用GitHub注册vercel的时候要手机号,但是一直出现这样的错误:the verification phone number has been temporarily blocked. please wait 12 hours and try again.
  • [技术干货] TypeScript接口:定义数据结构的契约-转载
     引言 在软件开发过程中,数据结构是不可避免的。不同的数据结构用于描述不同的实体和关系。定义数据结构有时需要更为精确和严格的方式,以避免在多人合作或迭代过程中出现误解和错误。在这种情况下, TypeScript 接口就成为了一种强有力的工具,可以定义数据结构的契约,从而确保数据在应用程序中的正确性和可维护性。  但是,仅仅使用基本类型、数组和对象等数据类型并不足以满足复杂应用程序中的数据结构需求。这时, TypeScript 接口就可以派上用场了。  什么是接口 在 TypeScript 中,接口是指一组方法和属性的声明,用于定义一个对象的形状。它只定义了对象所应该有的成员,而不关心对象的具体实现。接口可以被类、函数、对象等各种类型实现,从而使得这些实现具有相同的形状和属性。 使用接口可以方便地定义类型,从而避免了在代码中使用硬编码来定义对象的类型。它可以让代码更加清晰、可读、可维护,同时也可以提高代码的复用性和可扩展性。 接口的定义 接口的定义使用 interface 关键字,语法如下: interface InterfaceName {     property1: type1;     property2: type2;     method1(param1: type1, param2: type2): returnType;     method2(param1: type1): void; } 其中,InterfaceName 指定了接口的名称,property1、property2 是接口的属性,method1、method2 是接口的方法。属性和方法都有自己的名称和类型声明。 下面是一个简单的接口定义例子: interface Person {     name: string;     age: number;     sayHi(): void; } 这个接口定义了一个 Person 类型,它有两个属性和一个方法。 name 和 age 属性分别是字符串和数字类型, sayHi 方法没有参数,返回值为空。 接口的实现 在 TypeScript 中,接口可以被任何类型实现,包括类、函数、对象等。当一个类型实现了某个接口时,它必须满足该接口的所有定义,包括属性和方法的类型和名称。 下面是一个类实现接口的例子: interface Person {     name: string;     age: number;     sayHi(): void; }  class Student implements Person {     name: string;     age: number;     constructor(name: string, age: number) {         this.name = name;         this.age = age;     }     sayHi(): void {         console.log(`Hi, my name is ${this.name}, I'm ${this.age} years old.`);     } }  const student = new Student("Alice", 18); student.sayHi(); 在这个例子中,我们定义了一个 Person 接口,并让Student类实现了该接口。在Student类中,我们定义了 name 和 age 属性,并实现了 sayHi 方法。由于 Student 类实现了 Person 接口,因此它必须满足接口的所有定义。在实例化这个类时,可以看到输出了正确的信息。 TypeScript接口的继承 TypeScript 接口也可以 继承其他接口 ,从而可以更好地描述数据结构的关系。以下是一个继承接口的例子: interface Cancer {     name: string;     symptom: string; }  interface LungCancer extends Cancer {     smoking: boolean; } 上面的代码定义了两个接口,“ Cancer ”和“ LungCancer ”。显然,“ LungCancer ”继承了“ Cancer ”的属性,并增加了一个“ smoking ”属性。这种方式可以方便地描述数据结构的层次关系。 接口的可选属性和只读属性 可选属性 有时候我们定义的数据结构并不一定需要所有的属性,在这种情况下,我们可以使用可选属性。可选属性在属性名后面加上一个 ? 标记,表示该属性是可选的。例如: interface Person {     name: string;     age?: number;     sayHi(): void; }  const person1: Person = {     name: "Bob",     sayHi() {         console.log(`Hi, my name is ${this.name}.`);     }, };  const person2: Person = {     name: "Alice",     age: 18,     sayHi() {         console.log(`Hi, my name is ${this.name}, I'm ${this.age} years old.`);     }, }; 在这个例子中, Person 接口的 age 属性是可选的,因此我们可以在实现该接口的对象中省略 age 属性。在上面的 person1 对象中,我们只实现了 name 和 sayHi 属性,而没有实现 age 属性。在 person2 对象中,我们实现了所有的属性和方法。 只读属性 另外,有些时候我们希望定义一些只读的属性,这些属性只能在声明时被赋值,之后就不能被修改了。在 TypeScript 中,我们可以使用 readonly 关键字来定义只读属性。例如: interface Person {     readonly name: string;     age?: number;     sayHi(): void; }  const person: Person = {     name: "Alice",     age: 18,     sayHi() {         console.log(`Hi, my name is ${this.name}, I'm ${this.age} years old.`);     }, };  在这个例子中,我们定义了一个 Person 接口,并将 name 属性定义为只读属性。在实现该接口的对象中,我们无法修改 name 属性的值,因此在赋值时会出现编译错误。 TypeScript接口的函数类型 在 TypeScript 中,接口不仅可以描述对象,还可以描述函数类型。以下是一个函数类型的例子: interface SearchFunc {     (source: string, subString: string): boolean; }  let mySearch: SearchFunc; mySearch = function(source: string, subString: string): boolean {     let result = source.search(subString);     return result > -1; } 上面的代码定义了一个函数类型的接口“ SearchFunc ”,它描述了一个具有两个参数和一个布尔类型返回值的函数。在实例化这个函数类型的时候,“ mySearch ”变量被赋值为符合这个函数类型的函数。 TypeScript接口的类类型 在 TypeScript 中,接口还可以描述类的属性和方法。以下是一个例子: interface ClockInterface {     currentTime: Date;     setTime(d: Date): void; }  class Clock implements ClockInterface {     currentTime: Date = new Date();     setTime(d: Date) {         this.currentTime = d;     }     constructor(h: number, m: number) {     } } 上面的代码定义了一个接口“ ClockInterface ”,它描述了一个具有“ currentTime ”和“ setTime ”方法的类。然后,我们定义了一个“ Clock ”类,并实现了这个接口。当我们实例化这个类的时候,它必须符合接口的描述,即含有“ currentTime ”属性和“ setTime ”方法。 总结 在 TypeScript 中,接口是定义数据结构的契约,用于确保代码的健壮性和可维护性。它可以被任何类型实现,包括类、函数、对象等。接口可以定义属性、方法、可选属性、只读属性等,从而使代码更加清晰、可读、可维护。接口的使用可以提高代码的复用性和可扩展性,是 TypeScript 中一个非常重要的概念。 ———————————————— 版权声明:本文为CSDN博主「与墨学长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/McapricornZ/article/details/131340880 
  • [其他问题] typescript中定义枚举变量,赋值报错是怎么回事?
    下面的给nodeInfo.nodeType中的枚举变量赋值怎么会报错?定义:interface IPlayer {playerName:String; playerColor:Color;}export const enum enumNodeType {Troop, City}interface nodeInfo {playerInfo:IPlayer; nodeType:enumNodeType}在函数中使用:let nodeInfo:nodeInfo;nodeInfo.nodeType = enumNodeType.City  // 这里报错,是怎么回事?同一个文件中
  • [技术干货] TypeScript 这十年-转载
    【CSDN 编者按】很多时候,仅从名称上来看,不少人对 TypeScript 与 JavaScript 傻傻分不清楚,或许只知道 TypeScript 作为 JavaScript 的后来者,想要将其取而代之,却时至今日未能如愿。殊不知,TypeScript 诞生落地发展到当下,已有十年的时间。虽然未能达到 JavaScript 流行的高度,但也弥补了其不少不足之处。近日,微软 TypeScript 高级项目经理 Daniel Rosenwasser 在官网发文分享了 TypeScript 从早期到时间考验再到今天的整个演进历程,也带来了不一样的思考。原文地址:https://devblogs.microsoft.com/typescript/ten-years-of-typescript/编译 | 苏宓 出品 | CSDN(ID:CSDNnews)以下为译文:今天是 TypeScript 的生日!但是这个生日很特别——10 年前的今天,2012 年 10 月 1 日,TypeScript 首次公开亮相。早期的情况当 TypeScript 首次亮相时,有很多人持怀疑态度,这也是可以理解的。对于一些 JavaScript 用户来说,一个试图将静态类型引入 JavaScript 的团队可能听起来像是一个邪恶的组织,甚至可视为一个阴谋或笑话。但是这些功能是有价值的,对吗?类型检查,在你保存文件之前捕捉 Bug,并获得丰富的编辑器功能,如代码完成、导航和重构?我们知道公司内外部的团队在处理复杂的 JavaScript 代码库时遇到了巨大的挑战,而且我们知道 JavaScript 将被广泛使用。因此,谁不希望有强大的工具来帮助编写它呢?对于团队来说,TypeScript 初心未变,一如最初在发布 TypeScript 时所述的那样,“在大型应用开发中使用 JavaScript 开发!"。幸运的是,这个愿景使得很多的开发者产生了共鸣。在早期,我们建立了一个小而勤奋、热情的社区,当我们还在迭代、学习和构建一个甚至还没有达到 1.0 的东西时,很多人就愿意参与进来,进行实验和体验。我们看到了令人兴奋的新努力,如 DefinitelyTyped 项目,新的社区成员在 StackOverflow 和我们的问题跟踪器上提供帮助,创作者为该语言编写书籍和教程,以及押注 TypeScript 的新库。这些有耐心、努力工作、精力充沛的开发者为 TypeScript 社区的发展奠定了基础。不过,大多数 JavaScript 开发人员对 TypeScript 仍持怀疑态度。那么,这个团队要如何说服 JavaScript 开发者相信静态类型在动态类型语言中的价值?"类型与无类型"一直是一个有争议的话题,这在编程界至少可以追溯到半个世纪以前。但是,我们真的想通过类型的力量来创造令人惊奇的 JavaScript 工具。这能做到吗?经得起时间的考验事实是,这需要一种与我们习惯的完全不同的开发方法,其次是需要大家坚持不懈、拓展性和同理心。TypeScript 必须是免费和开源的,并以真正开放的方式进行。它还必须与现有的 JavaScript 无缝互通,与 JavaScript 共同发展,并且感觉像 JavaScript。TypeScript 从未打算建立一种单独的、独特的、规定性的语言。相反,TypeScript 必须是描述性——围绕 JavaScript 生态系统中一些模式进行类型系统的创新。这让我们能够满足人们的需求,而且这种理念与项目的设计目标非常吻合。实际上,TypeScript 的设计目标保持得如此之好,令人惊讶。例如,一些设计目标:"不会对发出的程序施加任何运行时开销。""与当前和未来的 ECMAScript 提案保持一致。""保留所有 JavaScript 代码的运行时行为。""避免增加表达式级别的语法。""使用一致的、完全可擦除的、结构化的类型系统。"所有真正指向 TypeScript 只是简单地成为 JavaScript 的类型检查器,只添加类型检查所需的语法。因此,我们主要关注类型系统,而避免增加新的运行时语法和行为。这在 10 年后的应用中,体现地可能更明显,但编程语言经常试图根据他们的可运行代码的样子来区分自己。此外,很多类型化语言根据类型来指导他们的运行时行为。但是,这些方法在试图建立在 JavaScript 的基础上,并与之整合时,就没有意义了。没有类型的 JavaScript 在粘贴到 TypeScript 文件中时,必须有相同的工作方式,而且将 TypeScript 转换为 JavaScript 需要像剥离类型一样容易。我们在早期采取了一些错误的措施才意识到这一点,但这是一个学习的机会,并且微软团队在 10 年的大部分时间里都避免了运行时语法。如今,当 TypeScript 缺少一个有用的运行时特性时,我们不会只在 TypeScript 中添加它。我们在 TC39(JavaScript 标准机构)内开始实践,指导或倡导新的功能,以便所有的 JavaScript 开发人员能够从中受益。另一个成功的原则是,TypeScript 并没有试图成为工具箱中的每一个工具。我们的一个非目标是不 "提供一个端到端的构建管道。相反,使系统具有可扩展性,以便外部工具可以使用编译器进行更复杂的构建工作流程"。有很多时候,TypeScript 被要求成为一个 linter、一个 bundler、一个优化器/minifier、一个构建协调器、再一个 bundler 等等。这些界限并不会每次被明确,尤其是当 TypeScript 作为一个类型检查器、编译器和语言服务已经做了很多。在 JavaScript 生态系统中,很多人参与到应用程序开发的最佳实践争斗中,由此 TypeScript 也不断地保持了灵活性,这一点非常重要。考虑到过去几年中,所有不同的捆绑器、不同的运行时、不同的构建协调器和不同的锁定器,TypeScript 与其中的每一个都很好地整合了,并没有试图取代其中的任何一个,这一点也至关重要。我们很荣幸能与这个领域的工具作者合作,因为我们都在努力使 TypeScript 和 JavaScript 更容易使用。回到今天今天,TypeScript 是一种蓬勃发展的语言,全世界有数百万的开发人员在使用。在 StackOverflow 的年度调查、GitHub 的 Octoverse 报告和 Redmonk的语言排名等调查和语言排名中,TypeScript 一直处于开发者最常用和最喜爱的语言中的 Top 10。当然,背景很重要——TypeScript 的使用从根本上与 JavaScript 的使用交织在一起,每个 TypeScript 开发者也是 JavaScript 开发者。值得庆幸的是,即使在询问 JavaScript 开发人员是否使用 TypeScript 并喜欢它时,比如在 JS 的状态调查中,答案也都会是 "是"!TypeScript 的成功是一个很好的例子。今天的成功远远超过了核心团队几年前对 TypeScript 的想象,更不用说十年前了。核心团队在 TypeScript 上努力工作,但我们知道,实现这一成功的根本原因是社区。这包括 TypeScript 的外部贡献者、在 TypeScript 上下注并证明该语言的库创建者和日常开发者、DefinitelyTyped 的贡献者、社区组织者、花时间回答问题和教导他人并为新人开辟道路的专家。也希望 TypeScript 的下一个 10 年能给你带来好的待遇!原文链接:https://blog.csdn.net/csdnnews/article/details/127236749?spm=1000.2115.3001.5927
  • [热门活动] C#、TypeScript 之父 Anders Hejlsberg:“会用 Excel 的,都是程序员 ”[转载]
    原文链接:https://thenewstack.io/microsofts-programming-language-czar-anders-hejlsberg-the-interview/                 https://blog.csdn.net/m0_66023967/article/details/123068356?spm=1000.2115.3001.5927Anders Hejlsberg是世界上最重要的计算机程序员之一。作为Turbo Pascal、Delphi、C#和TypeScript等编程语言的创造者,在构建微软.NET等开发环境方面极具影响力,Hejlsberg影响了数以百万计的软件开发人员。近日,Hejlsberg与TNS新闻编辑Darryl K.Taft进行了一场线上对话,围绕微软低代码/无代码、Web3等话题,分享了他对许多与软件开发相关的事情的看法。Excel是一种低代码/无代码工具问:您对于低代码,无代码有什么看法?Anders Hejlsberg:我认为这个领域的潜力巨大。我们常会忽略,其实我们已经拥有了世界上最好的编程语言之一,或许这取决于你如何定义Excel中编程语言。可以说Excel是一种低代码/无代码的程序编写方式,人们运行程序,而他们使用的电子表格就是程序。你可以做一些事情,输入一些东西,然后运行程序,程序会在电子表格的底层运行,并且给出结果。所以我认为挑战其实一直在于这些工具。当达到低代码环境的极限时,你需要找到设置合适的逃生舱口的方法,才不会陷入困境。而且这个逃生舱口,可以转移到一个更完整或完整的编程环境,这意味着有意义的可扩展性模型是必须的。因此,我们需要思考的事情还有很多,但这些事情往往不是最重要的,因为人们往往会转而关注绘制方框和线条,以及这些示例的演示效果。但我常常很好奇,这些工具是否能适应现实世界?很多都不能,但有些可以。这是有趣的地方。问:我的意思是,整体的主旨是努力让更多人进入开发的世界。其中一部分人想要走的更远,成为专业人士,或者至少更加熟练。Anders Hejlsberg:是的。如果你去问所有的Excel用户,他们都不会自称程序员。但是,从某种意义上来说,他们是。问:没错,我比较喜欢把这比作“Blue Apron”和“HelloFresh”这样的套餐服务——它们会让你开始学习烹饪,并且自己动手,做得更好。你认为在软件开发中下一个要克服的挑战是什么?Anders Hejlsberg:在我们写代码的方式和机器学习的可能够帮助我们的方式之间,仍然有非常大的差距。因为我们的大脑以及神经网络的工作方式,从来没有真正关于0和1以及绝对正确的答案,而都是统计和模糊逻辑。然而,所有的编程语言都牢固地扎根于逻辑和可证明性等等。这两种世界观之间存在着巨大的差距。看看我们最终如何弥合这一差距的(如果说我们最终做到了的话)。软件开发中的安全性问:下面我们来谈谈安全问题。在软件开发中,安全性和整个shift left的作用有多重要?Anders Hejlsberg:这取决于你在堆栈中的位置。对于编程语言来说,安全性非常重要,起码这对我的工作影响很大。甚至可以说类型检查器是一种安全形式。这是软件中可利用的漏洞。所以从这个意义上来说,编程语言间接地考虑了安全性。创造可以分析代码,并且指出可能存在的安全漏洞的工具,是我们看待安全性的其他方式。但很显然,这是个现实问题。我是说,世界各地也有人每天上班,他们的工作就是黑入西方国家的公司,从而获得薪水。这细思极恐。有很多人靠滥用科技谋生。虽然这一点令人难过,但这就是现实。Web3的开发问:您对Web3有什么看法?您认为是否需要新的工具进行Web3的开发呢?Anders Hejlsberg:首先,我们要对Web3的概念达成共识,因为人们对此总是各持己见。我喜欢奖励创造者概念,以及创造数字资产并获得奖励的能力。但是,在这个领域也有很多骗子、挂羊头卖狗肉的人和急功近利的人。而且还会造成大量的环境污染,虽然可以将其归因于一些正在进行的采矿活动和能源的使用,所以这是一个多样的世界。我们将看到这一切的结果。因此,我喜欢它的某些部分,也反对它的某些部分。潜力巨大的项目:GitHub构建的Copilot问:我知道您在微软需要做的事情很多,但在微软以外,有没有什么很棒的项目或者工作吸引您的关注?Anders Hejlsberg:我认为微软肯定有一些非常有趣的项目。比如开发者工具、人工智能、机器学习,还有很多其他有意思的事。不知道你是否了解GitHub正在构建的Copilot的项目,能够在世界上所有的开源代码上训练一个机器学习网络,然后让它给出答案,是不是很棒?当然,这仍然有点像西大荒,因为有各种机遇和不可掌控的发展,以及知识产权的未解决的问题,但它展现出巨大的潜力。所以我认为这很吸引人,我正在密切关注这个问题。问:我认为这是2021年的最好的编程项目,涉及到相当大的领域。Anders Hejlsberg:是的,这个项目确实很吸引人。尤其是作为一名程序员,它在很大程度上让人洞察到我们谈论的是什么样的智能。从某种意义上说,用智能这个词有点不恰当,因为如果有人以前写过这段代码,这种机器学习模型的聚合内存可能是正确的,这值得我们注意。它可以在其内存中找到那段代码。但是,如果以前没有人写过,它必须要思考解决方案,结果可能出人意料,所以在这方面还有很多需要思考的地方。但这是一个了不起的工具,因为它把再利用的概念提升到了一个新的水平,让我们不用重复做别人已经做过的事。
  • [技术干货] TypeScript 声明文件
    TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。假如我们想使用第三方库,比如 jQuery,我们通常这样获取一个 id 是 foo 的元素:$('#foo');// 或jQuery('#foo');但是在 TypeScript 中,我们并不知道 $ 或 jQuery 是什么东西:jQuery('#foo');// index.ts(1,1): error TS2304: Cannot find name 'jQuery'.这时,我们需要使用 declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对:declare var jQuery: (selector: string) => any;jQuery('#foo');declare 定义的类型只会用于编译时的检查,编译结果中会被删除。上例的编译结果是:jQuery('#foo');声明文件声明文件以 .d.ts 为后缀,例如:runoob.d.ts声明文件或模块的语法格式如下:declare module Module_Name {}TypeScript 引入声明文件语法格式:/// <reference path = " runoob.d.ts" />当然,很多流行的第三方库的声明文件不需要我们定义了,比如 jQuery 已经有人帮我们定义好了:jQuery in DefinitelyTyped。实例以下定义一个第三方库来演示:CalcThirdPartyJsLib.js 文件代码:var Runoob;  (function(Runoob) {    var Calc = (function () {         function Calc() {         }     })    Calc.prototype.doSum = function (limit) {        var sum = 0;          for (var i = 0; i <= limit; i++) {             sum = sum + i;         }        return sum;     }    Runoob.Calc = Calc;     return Calc; })(Runoob || (Runoob = {})); var test = new Runoob.Calc();如果我们想在 TypeScript 中引用上面的代码,则需要设置声明文件 Calc.d.ts,代码如下:Calc.d.ts 文件代码:declare module Runoob {    export class Calc {       doSum(limit:number) : number;    }}声明文件不包含实现,它只是类型声明,把声明文件加入到 TypeScript 中:CalcTest.ts 文件代码:/// <reference path = "Calc.d.ts" /> var obj = new Runoob.Calc(); // obj.doSum("Hello"); // 编译错误console.log(obj.doSum(10));下面这行导致编译错误,因为我们需要传入数字参数:obj.doSum("Hello");使用 tsc 命令来编译以上代码文件:tsc CalcTest.ts生成的 JavaScript 代码如下:CalcTest.js 文件代码:/// <reference path = "Calc.d.ts" /> var obj = new Runoob.Calc();//obj.doSum("Hello"); // 编译错误console.log(obj.doSum(10));
  • [技术干货] typescript 模块
    TypeScript 模块的设计理念是可以更换的组织代码。模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。 大家最熟知的JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js。此外还有有 SystemJs 和 Webpack。模块导出使用关键字 export 关键字,语法格式如下:// 文件名 : SomeInterface.ts export interface SomeInterface {    // 代码部分}要在另外一个文件使用该模块就需要使用 import 关键字来导入:import someInterfaceRef = require("./SomeInterface");实例IShape.ts 文件代码:/// <reference path = "IShape.ts" /> export interface IShape {    draw(); }Circle.ts 文件代码:import shape = require("./IShape"); export class Circle implements shape.IShape {    public draw() {       console.log("Cirlce is drawn (external module)");    } }Triangle.ts 文件代码:import shape = require("./IShape"); export class Triangle implements shape.IShape {    public draw() {       console.log("Triangle is drawn (external module)");    } }TestShape.ts 文件代码:import shape = require("./IShape"); import circle = require("./Circle"); import triangle = require("./Triangle");   function drawAllShapes(shapeToDraw: shape.IShape) {   shapeToDraw.draw(); }  drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle());使用 tsc 命令编译以上代码(AMD):tsc --module amd TestShape.ts 得到以下 JavaScript 代码:IShape.js 文件代码:define(["require", "exports"], function (require, exports) {});Circle.js 文件代码:define(["require", "exports"], function (require, exports) {   var Circle = (function () {      function Circle() {      }      Circle.prototype.draw = function () {         console.log("Cirlce is drawn (external module)");      };      return Circle;   })();   exports.Circle = Circle;});Triangle.js 文件代码:define(["require", "exports"], function (require, exports) {   var Triangle = (function () {      function Triangle() {      }      Triangle.prototype.draw = function () {         console.log("Triangle is drawn (external module)");      };      return Triangle;   })();   exports.Triangle = Triangle;});TestShape.js 文件代码:define(["require", "exports", "./Circle", "./Triangle"],    function (require, exports, circle, triangle) {      function drawAllShapes(shapeToDraw) {      shapeToDraw.draw();   }   drawAllShapes(new circle.Circle());   drawAllShapes(new triangle.Triangle());});使用 tsc 命令编译以上代码(Commonjs):tsc --module commonjs TestShape.ts得到以下 JavaScript 代码:Circle.js 文件代码:var Circle = (function () {   function Circle() {   }   Circle.prototype.draw = function () {      console.log("Cirlce is drawn");   };   return Circle;})(); exports.Circle = Circle;Triangle.js 文件代码:var Triangle = (function () {   function Triangle() {   }   Triangle.prototype.draw = function () {      console.log("Triangle is drawn (external module)");   };   return Triangle;})();exports.Triangle = Triangle;TestShape.js 文件代码:var circle = require("./Circle");var triangle = require("./Triangle"); function drawAllShapes(shapeToDraw) {   shapeToDraw.draw();}drawAllShapes(new circle.Circle());drawAllShapes(new triangle.Triangle());输出结果为:Cirlce is drawn (external module)Triangle is drawn (external module)
  • [技术干货] typescript命名空间
    命名空间一个最明确的目的就是解决重名问题。假设这样一种情况,当一个班上有两个名叫小明的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的姓(王小明,李小明),或者他们父母的名字等等。命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。TypeScript 中命名空间使用 namespace 来定义,语法格式如下:namespace SomeNameSpaceName {    export interface ISomeInterfaceName {      }     export class SomeClassName {      }  }以上定义了一个命名空间 SomeNameSpaceName,如果我们需要在外部可以调用 SomeNameSpaceName 中的类和接口,则需要在类和接口添加 export 关键字。要在另外一个命名空间调用语法格式为:SomeNameSpaceName.SomeClassName;如果一个命名空间在一个单独的 TypeScript 文件中,则应使用三斜杠 /// 引用它,语法格式如下:/// <reference path = "SomeFileName.ts" />以下实例演示了命名空间的使用,定义在不同文件中:IShape.ts 文件代码:namespace Drawing {     export interface IShape {         draw();     }}Circle.ts 文件代码:/// <reference path = "IShape.ts" /> namespace Drawing {     export class Circle implements IShape {         public draw() {             console.log("Circle is drawn");         }      }}Triangle.ts 文件代码:/// <reference path = "IShape.ts" /> namespace Drawing {     export class Triangle implements IShape {         public draw() {             console.log("Triangle is drawn");         }     } }TestShape.ts 文件代码:/// <reference path = "IShape.ts" />   /// <reference path = "Circle.ts" /> /// <reference path = "Triangle.ts" />  function drawAllShapes(shape:Drawing.IShape) {     shape.draw(); } drawAllShapes(new Drawing.Circle());drawAllShapes(new Drawing.Triangle());使用 tsc 命令编译以上代码:tsc --out app.js TestShape.ts  得到以下 JavaScript 代码:JavaScript/// <reference path = "IShape.ts" /> var Drawing;(function (Drawing) {    var Circle = /** @class */ (function () {        function Circle() {        }        Circle.prototype.draw = function () {            console.log("Circle is drawn");        };        return Circle;    }());    Drawing.Circle = Circle;})(Drawing || (Drawing = {}));/// <reference path = "IShape.ts" /> var Drawing;(function (Drawing) {    var Triangle = /** @class */ (function () {        function Triangle() {        }        Triangle.prototype.draw = function () {            console.log("Triangle is drawn");        };        return Triangle;    }());    Drawing.Triangle = Triangle;})(Drawing || (Drawing = {}));/// <reference path = "IShape.ts" />   /// <reference path = "Circle.ts" /> /// <reference path = "Triangle.ts" />  function drawAllShapes(shape) {    shape.draw();}drawAllShapes(new Drawing.Circle());drawAllShapes(new Drawing.Triangle());使用 node 命令查看输出结果为:$ node app.jsCircle is drawnTriangle is drawn嵌套命名空间命名空间支持嵌套,即你可以将命名空间定义在另外一个命名空间里头。namespace namespace_name1 {     export namespace namespace_name2 {        export class class_name {    }     } }成员的访问使用点号 . 来实现,如下实例:Invoice.ts 文件代码:namespace Runoob {    export namespace invoiceApp {       export class Invoice {          public calculateDiscount(price: number) {             return price * .40;          }       }    } }InvoiceTest.ts 文件代码:/// <reference path = "Invoice.ts" />var invoice = new Runoob.invoiceApp.Invoice(); console.log(invoice.calculateDiscount(500));使用 tsc 命令编译以上代码:tsc --out app.js InvoiceTest.ts得到以下 JavaScript 代码:JavaScriptvar Runoob;(function (Runoob) {    var invoiceApp;    (function (invoiceApp) {        var Invoice = /** @class */ (function () {            function Invoice() {            }            Invoice.prototype.calculateDiscount = function (price) {                return price * .40;            };            return Invoice;        }());        invoiceApp.Invoice = Invoice;    })(invoiceApp = Runoob.invoiceApp || (Runoob.invoiceApp = {}));})(Runoob || (Runoob = {}));/// <reference path = "Invoice.ts" />var invoice = new Runoob.invoiceApp.Invoice();console.log(invoice.calculateDiscount(500));使用 node 命令查看输出结果为:$ node app.js200
  • [技术干货] TypeScript 类(下)
    继承类的方法重写类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写。其中 super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法。TypeScriptclass PrinterClass {    doPrint():void {      console.log("父类的 doPrint() 方法。")    } }  class StringPrinter extends PrinterClass {    doPrint():void {       super.doPrint() // 调用父类的函数      console.log("子类的 doPrint()方法。")   } }编译以上代码,得到以下 JavaScript 代码:JavaScriptvar obj = new StringPrinter() obj.doPrint() var __extends = (this && this.__extends) || (function () {    var extendStatics = function (d, b) {        extendStatics = Object.setPrototypeOf ||            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };        return extendStatics(d, b);    };    return function (d, b) {        extendStatics(d, b);        function __() { this.constructor = d; }        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());    };})();var PrinterClass = /** @class */ (function () {    function PrinterClass() {    }    PrinterClass.prototype.doPrint = function () {        console.log("父类的 doPrint() 方法。");    };    return PrinterClass;}());var StringPrinter = /** @class */ (function (_super) {    __extends(StringPrinter, _super);    function StringPrinter() {        return _super !== null && _super.apply(this, arguments) || this;    }    StringPrinter.prototype.doPrint = function () {        _super.prototype.doPrint.call(this); // 调用父类的函数        console.log("子类的 doPrint()方法。");    };    return StringPrinter;}(PrinterClass));var obj = new StringPrinter();obj.doPrint();输出结果为:父类的 doPrint() 方法。子类的 doPrint()方法。static 关键字static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。TypeScriptclass StaticMem {     static num:number;       static disp():void {       console.log("num 值为 "+ StaticMem.num)    } }  StaticMem.num = 12     // 初始化静态变量StaticMem.disp()       // 调用静态方法编译以上代码,得到以下 JavaScript 代码:JavaScriptvar StaticMem = /** @class */ (function () {    function StaticMem() {    }    StaticMem.disp = function () {        console.log("num 值为 " + StaticMem.num);    };    return StaticMem;}());StaticMem.num = 12; // 初始化静态变量StaticMem.disp(); // 调用静态方法输出结果为:num 值为 12instanceof 运算符instanceof 运算符用于判断对象是否是指定的类型,如果是返回 true,否则返回 false。TypeScriptclass Person{ } var obj = new Person() var isPerson = obj instanceof Person; console.log("obj 对象是 Person 类实例化来的吗? " + isPerson);编译以上代码,得到以下 JavaScript 代码:JavaScriptvar Person = /** @class */ (function () {    function Person() {    }    return Person;}());var obj = new Person();var isPerson = obj instanceof Person;console.log(" obj 对象是 Person 类实例化来的吗? " + isPerson);输出结果为:obj 对象是 Person 类实例化来的吗? true访问控制修饰符TypeScript 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。TypeScript 支持 3 种不同的访问权限。public(默认) : 公有,可以在任何地方被访问。protected : 受保护,可以被其自身以及其子类和父类访问。private : 私有,只能被其定义所在的类访问。以下实例定义了两个变量 str1 和 str2,str1 为 public,str2 为 private,实例化后可以访问 str1,如果要访问 str2 则会编译错误。TypeScriptclass Encapsulate {    str1:string = "hello"    private str2:string = "world" } var obj = new Encapsulate() console.log(obj.str1)     // 可访问 console.log(obj.str2)   // 编译错误, str2 是私有的类和接口类可以实现接口,使用关键字 implements,并将 interest 字段作为类的属性使用。以下实例红 AgriLoan 类实现了 ILoan 接口:TypeScriptinterface ILoan {    interest:number }  class AgriLoan implements ILoan {    interest:number    rebate:number       constructor(interest:number,rebate:number) {       this.interest = interest       this.rebate = rebate    } }  var obj = new AgriLoan(10,1) console.log("利润为 : "+obj.interest+",抽成为 : "+obj.rebate )编译以上代码,得到以下 JavaScript 代码:JavaScriptvar AgriLoan = /** @class */ (function () {    function AgriLoan(interest, rebate) {        this.interest = interest;        this.rebate = rebate;    }    return AgriLoan;}());var obj = new AgriLoan(10, 1);console.log("利润为 : " + obj.interest + ",抽成为 : " + obj.rebate);输出结果为:利润为 : 10,抽成为 : 1
总条数:42 到第
上滑加载中