iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >TypeScript 4.1中的模板字面类型是什么
  • 149
分享到

TypeScript 4.1中的模板字面类型是什么

2023-06-15 20:06:31 149人浏览 泡泡鱼
摘要

这篇文章主要介绍“typescript 4.1中的模板字面类型是什么”,在日常操作中,相信很多人在TypeScript 4.1中的模板字面类型是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”TypeScr

这篇文章主要介绍“typescript 4.1中的模板字面类型是什么”,在日常操作中,相信很多人在TypeScript 4.1中的模板字面类型是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”TypeScript 4.1中的模板字面类型是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

新的语言特性

模板字面类型

es6 开始,我们就可以通过模板字面量(Template Literals)的特性,用反引号来书写字符串,而不只是单引号或双引号:

const message = `text`;

正如 Flavio Copes 所言,模板字面量提供了之前用引号写的字符串所不具备的特性:

  • 定义多行字符串非常方便

  • 可以轻松地进行变量和表达式的插值

  • 可以用模板标签创建 DSL(Domain Specific Language,领域特定语言)

模板字面量类型和 javascript 中的模板字符串语法完全一致,只不过是用在类型定义里面:

type Entity = 'Invoice';  type Notification = `${Entity} saved`; // 等同于 // type Notification = 'Invoice saved';   type Viewport = 'md' | 'xs'; type Device = 'mobile' | 'desktop';  type Screen = `${Viewport | Device} screen`; // 等同于下面这一行 // type Screen = 'md screen' | 'xs screen' | 'mobile screen' | 'desktop screen';

当我们定义了一个具体的字面量类型时,TypeScript 会通过拼接内容的方式产生新的字符串字面量类型。

键值对类型中键的重新映射(Key Remapping)

映射类型可以基于任意键创建新的对象类型。 字符串字面量可以用作映射类型中的属性名称:

type Actions = { [K in 'showEdit' | 'showCopy' | 'showDelete']?: boolean; }; // 等同于 type Actions = {   showEdit?:   boolean,   showCopy?:   boolean,   showDelete?: boolean };

如果你想创建新键或过滤掉键,TypeScript 4.1 允许你使用新的 as 子句重新映射映射类型中的键:

type MappedTypeWithNewKeys<T> = {     [K in keyof T as NewKeyType]: T[K] }

TypeScript Remapping KeysThe new as clause lets you leverage features like  template literal types to easily create new property names based on old ones.  Keys can be filtered by producing never so that you don&rsquo;t have to use an extra  Omit helper type in some cases: 通过使用新的 as  子句,我们可以利用模板字面量类型之类的特性轻松地基于旧属性创建新属性名称。我们可以通过输出 never 来过滤键,这样在某些情况下就不必使用额外的 Omit  辅助类型:

type Getters<T> = {     [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K] };  interface Person {     name: string;     age: number;     location: string; }  type LazyPerson = Getters<Person>; //   ^ = type LazyPerson = { //       getName: () => string; //       getAge: () => number; //       getLocation: () => string; //   }  // 去掉 'kind' 属性 type RemoveKindField<T> = {     [K in keyof T as Exclude<K, "kind">]: T[K] };  interface Circle {     kind: "circle";     radius: number; }  type KindlessCircle = RemoveKindField<Circle>; //   ^ = type KindlessCircle = { //       radius: number; //   }

TypeScript 利用带有 as 子句的模板文字类型 (source)

JSX 工厂函数

jsX 代表 JavaScript XML,它允许我们使用 JavaScript 编写 html 元素并将其放置在 DOM 中,而无需任何  createElement() 或 appendChild() 方法,例如:

const greeting = <h5>Yes I can do it!</h5>; ReactDOM.render(greeting, document.getElementById('root'));

TypeScript 4.1 通过编译器选项 jsx 的两个新选项支持 React 17 的 jsx 和 jsxs 工厂函数:

  • react-jsx

  • react-jsxdev

“这些选项分别用于生产和开发编译。通常,一个选项可以扩展自另一个选项。” &mdash; TypeScript发版说明

以下是两个用于生产和开发的 TypeScript 配置文档的两个示例:

// ./src/tsconfig.JSON {   "compilerOptions": {     "module": "esnext",     "target": "es2015",     "jsx": "react-jsx",     "strict": true   },   "include": [".*"] }

开发配置:

// ./src/tsconfig.dev.json {   "extends": "./tsconfig.json",   "compilerOptions": {     "jsx": "react-jsxdev"   } }

如下图所示,TypeScript 4.1 支持在像 React 这样的 JSX 环境中进行类型检查:

TypeScript 4.1中的模板字面类型是什么  

递归条件类型

另一个新增功能是递归条件类型,它允许它们在分支中引用自己,从而能够更灵活地处理条件类型,使得编写递归类型别名更加容易。下面是一个使用 Awaited  展开深层嵌套的 Promise 的示例:

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;  // 类似 `promise.then(...)`, 但是在类型上更加精确 declare function customThen<T, U>(     p: Promise<T>,     onFulfilled: (value: Awaited<T>) => U ): Promise<Awaited<U>>;

但是应当注意的是,TypeScript 需要更多时间来进行递归类型的类型检查。Microsoft 警告,应以负责任的态度谨慎使用它们。

Checked indexed accesses 索引访问检查

_ TypeScript 中的索引签名允许可以像下面的 Options 接口中那样访问任意命名的属性:

interface Options {   path: string;   permissions: number;    // Extra properties are caught by this index signature.   // 额外的属性将被这个   [propName: string]: string | number; }  function checkOptions(opts: Options) {   opts.path; // string   opts.permissions; // number    // 这些都可以!因为类型都是 string | number   opts.yadda.toString();   opts["foo bar baz"].toString();   opts[Math.random()].toString(); }

在这里,我们看到不是 path 以及 permissions 的属性应具有 string | number 类型:

TypeScript 4.1 提供了一个新的标志 --noUncheckedIndexedAccess,使得每次属性访问(如  opts.path)或索引访问(如 opts [“ blabla”] )都可能未定义。这意味着如果我们需要访问上一个示例中的 opts.path  之类的属性,则必须检查其是否存在或使用非 null 断言运算符(后缀 ! 字符):

function checkOptions(opts: Options) {   opts.path; // string   opts.permissions; // number    // 以下代码在 noUncheckedIndexedAccess 开启时是非法的   opts.yadda.toString();   opts["foo bar baz"].toString();   opts[Math.random()].toString();    // 检查属性是否真的存在   if (opts.yadda) {     console.log(opts.yadda.toString());   }    // 直接使用非空断言操作符   opts.yadda!.toString(); }

--noUncheckedIndexedAccess 标志对于捕获很多错误很有用,但是对于很多代码来说可能很嘈杂。 这就是为什么 --strict  开关不会自动启用它的原因。

不需要 baseUrl 指定路径

在 TypeScript 4.1 之前,要能够使用 tsconfig.json 文件中的 paths,必须声明 baseUrl 参数。  在新版本中,可以在不带 paths 选项的情况下指定 baseUrl。 这解决了自动导入中路径不畅的问题。

{     "compilerOptions": {         "baseUrl": "./src",         "paths": {             "@shared": ["@shared/"] // This mapping is relative to "baseUrl"         }     } }

checkJs 默认打开 allowJs

如果您有一个 JavaScript 项目,正在其中使用 checkJs 选项检查 .js 文件中的错误,则还应该声明 allowJs 以允许编译  JavaScript 文件。而 TypeScript 4.1 中,默认情况下 checkJs 意味着 allowJs:

{   compilerOptions: {     allowJs: true,     checkJs: true   } }

JSDoc @see 标签的编辑器支持

在编辑器中使用 TypeScript 时,现在对 JSDoc 标签 @see 有了更好的支持,这将改善TypeScript 4.1的可用性:

// @filename: first.ts export class C {}  // @filename: main.ts import * as first from "./first";   function related() {}

不兼容改变

lib.d.ts 变动

结构和 DOM 的环境声明,使您可以轻松地开始编写经过类型检查的 JavaScript 代码。

该文件自动包含在 TypeScript 项目的编译上下文中。 您可以通过指定 --noLib 编译器命令行标志或在 tsconfig.json 中配置  noLib 为 true 来排除它。

在 TypeScript 4.1 中,由于 DOM 类型是自动生成的,lib.d.ts 可能具有一组变动的 API,例如,从 ES2016 中删除的  Reflect.enumerate。

abstract 成员不能被标记为 async

在另一个重大更改中,标记为 abstract 的成员不能被再标记为 async。 因此,要修复您的代码,必须删除 async 关键字:

abstract class MyClass {   // 在 TypeScript 4.1 中必须删除 async   abstract async create(): Promise<string>; }

any/unknown 向外传播

在 TypeScript 4.1 之前,对于像 foo && somethingElse 这样的表达式, foo 的类型是 any 或  unknown。 整个表达式的类型将是 somethingElse 的类型,在以下示例中就是 {someProp:string} :

declare let foo: unknown; declare let somethingElse: { someProp: string }; let x = foo && somethingElse;

在 TypeScript 4.1 中, any 和 unknown 都将向外传播,而不是在右侧传播。通常,这个变更合适的解决方法是从 foo  && someExpression 切换到 !!foo && someExpression。

  • 注意:双重感叹号(!!)是将变量强制转换为布尔值(真或假)的一种简便方法。

Promise 中 resolve 的参数不再是可选类型

Promise 中 resolve 的参数不再是可选的,例如下面的代码:

new Promise((resolve) => {   doSomethingAsync(() => {     doSomething();     resolve();   }); });

这段代码在 TypeScript 4.1 中编译会报错:

resolve()   ~~~~~~~~~ error TS2554: Expected 1 arguments, but Got 0.   An argument for 'value' was not provided.

要解决这个问题,必须在 Promise 中给 resolve 提供至少一个值,否则,在确实需要不带参数的情况下调用 resolve()  的情况下,必须使用显式的 void 泛型类型参数声明 Promise:

new Promise<void>((resolve) => {   doSomethingAsync(() => {     doSomething();     resolve();   }); });

条件展开将会创建可选属性

在 JavaScript 中,展开运算符 { ...files } 不会作用于假值,例如 files 为 null 或者 undefined。

在以下使用条件传播的示例中,如果定义了 file,则将传播 file.owner 的属性。否则,不会将任何属性传播到返回的对象中:

function getOwner(file?: File) {   return {     ...file?.owner,     defaultUserId: 123,   }; }

在TypeScript 4.1之前, getOwner 返回基于每个展开对象的联合类型:

{ x: number } | { x: number, name: string, age: number, location: string }
  • 如果定义了 file,则会拥有来自Person(所有者的类型)的所有属性。

  • 否则,结果中一个都不会展示

但是事实证明,这样的代价最终会变得非常高昂,而且通常无济于事。在单个对象中存在数百个展开对象,每个展开对象都可能增加数百或数千个属性。  为了更好的性能,在TypeScript 4.1中,返回的类型有时使用全部可选属性:

{     x:         number;     name?:     string;     age?:      number;     location?: string; }

不匹配的参数将不再关联

过去,彼此不对应的参数在 TypeScript 中通过将它们与 any 类型关联而彼此关联。

在下面的重载示例(为同一功能提供多种功能类型)中, pickCard 函数将根据用户传入的内容返回两个不同的内容。如果用户传入表示 deck  的对象,则该函数将选择 card。 如果用户选择了 card,他们将得到他们选择的 card:

let suits = ["hearts", "spades", "clubs", "diamonds"];  function pickCard(x: { suit: string; card: number }[]): number; function pickCard(x: number): { suit: string; card: number }; function pickCard(x: any): any {   // Check to see if we're working with an object/array   // if so, they gave us the deck and we'll pick the card   if (typeof x == "object") {     let pickedCard = Math.floor(Math.random() * x.length);     return pickedCard;   }   // Otherwise just let them pick the card   else if (typeof x == "number") {     let pickedSuit = Math.floor(x / 13);     return { suit: suits[pickedSuit], card: x % 13 };   } }  let myDeck = [   { suit: "diamonds", card: 2 },   { suit: "spades", card: 10 },   { suit: "hearts", card: 4 }, ];  let pickedCard1 = myDeck[pickCard(myDeck)]; alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);  let pickedCard2 = pickCard(15); alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

使用 TypeScript 4.1,某些情况下赋值将会失败,而某些情况下的重载解析则将失败。解决方法是,最好使用类型断言来避免错误。

到此,关于“TypeScript 4.1中的模板字面类型是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: TypeScript 4.1中的模板字面类型是什么

本文链接: https://www.lsjlt.com/news/281531.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • TypeScript 4.1中的模板字面类型是什么
    这篇文章主要介绍“TypeScript 4.1中的模板字面类型是什么”,在日常操作中,相信很多人在TypeScript 4.1中的模板字面类型是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”TypeScr...
    99+
    2023-06-15
  • TypeScript数据类型中模板字面量的示例分析
    这篇文章主要为大家展示了“TypeScript数据类型中模板字面量的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“TypeScript数据类型中模板字面...
    99+
    2024-04-02
  • TypeScript中的递归类型是什么
    这篇文章主要讲解了“TypeScript中的递归类型是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“TypeScript中的递归类型是什么”吧!什么是递归类型?递归类型是指一个类型在定义...
    99+
    2023-07-05
  • TypeScript的交叉类型和联合类型是什么
    这篇文章主要介绍了TypeScript的交叉类型和联合类型是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇TypeScript的交叉类型和联合类型是什么文章都会有所收获,下面我们一起来看看吧。交叉类型(In...
    99+
    2023-07-04
  • 泛型类与函数模板的区别是什么?
    泛型类定义新数据类型,而函数模板定义算法。泛型类通过指定类型参数实例化,函数模板通过调用实例化。泛型类可以继承,而函数模板不能。 泛型类与函数模板的区别 泛型类和函数模板都是 C++ ...
    99+
    2024-04-24
    泛型 函数模板 c++ 作用域
  • js中什么是模板字符串
    这篇文章主要为大家展示了“js中什么是模板字符串”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“js中什么是模板字符串”这篇文章吧。什么是模板字符串?模板字符串是...
    99+
    2024-04-02
  • C++STL中vector模板类是什么
    小编给大家分享一下C++STL中vector模板类是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vector模板类创建vector对象,遍历元素vector...
    99+
    2023-06-29
  • C++非类型类模板参数的基本概念是什么
    C++非类型类模板参数的基本概念是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。C++编程语言已经出现就立即引起了开发人员的注意,它具有C语言的所用功能,并...
    99+
    2023-06-17
  • 详解TypeScript映射类型和更好的字面量类型推断
    目录概述使用映射类型构建 Object.freeze()映射类型的语法更直观解释更多映射类型的示例映射类型的实际用例更好的字面量类型推断更好的 const 变量推断更好的只读属性推断...
    99+
    2024-04-02
  • JS ES中模板字符串是什么
    这篇文章主要介绍了JS ES中模板字符串是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.模板字符串是什么模板字符串( Template String )是增...
    99+
    2023-06-21
  • C++中的模板是什么?
    模板是一种 c++++ 特性,允许创建可重用代码,无需编写多个版本。使用泛型类型作为参数,可以在编译时创建定制的数据类型或算法。主要优势包括代码重用性、类型安全性、性能优化、可扩展性。需...
    99+
    2024-05-08
    c++ 模板
  • TypeScript中的接口和泛型是什么
    这篇文章给大家分享的是有关TypeScript中的接口和泛型是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。接口使用 interface 关键字来定义数据类型对象类型当存在于较长的数据类型约束时,我们可以通过...
    99+
    2023-06-29
  • Python中的Flask模板是什么
    Python中的Flask模板是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在一般的 Web 程序里,访问一个地址通常会返回一个包含各类信息的 HTML 页面。因为我们的...
    99+
    2023-06-25
  • Xamarin XAML语言中模板页面TemplatedPage是什么
    这篇文章将为大家详细讲解有关Xamarin XAML语言中模板页面TemplatedPage是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。模板页面TemplatedPage之前我们提到了Templa...
    99+
    2023-06-04
  • C++ 函数模板中的类模板是如何使用的?
    C++ 函数模板中的类模板 C++ 函数模板可以感知类模板,并利用它们作为参数类型。这允许您创建通用函数,适用于各种数据类型和结构。 语法template<typename T&...
    99+
    2024-04-15
    c++ 函数模板 代码可读性
  • TypeScript类型实现加减乘除的方法是什么
    这篇文章主要介绍了TypeScript类型实现加减乘除的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇TypeScript类型实现加减乘除的方法是什么文章都会有所收获,下面我们一起来看看吧。引言在网上...
    99+
    2023-07-06
  • mysql汉字用的类型是什么
    本篇内容主要讲解“mysql汉字用的类型是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql汉字用的类型是什么”吧! 在m...
    99+
    2023-02-13
    mysql
  • Hybris DDIC类型及其对应的模型类是什么
    这篇文章主要讲解了“Hybris DDIC类型及其对应的模型类是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hybris DDIC类型及其对应的模型类是什么”吧!在ABAP里,我们在S...
    99+
    2023-06-04
  • MySQL中BLOB字段类型的作用是什么
    MySQL中BLOB字段类型的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。BLOB类型的字段用于存储二进制数据MySQL中,BLO...
    99+
    2024-04-02
  • TypeScript中函数与类的概念是什么
    这篇文章主要讲解了“TypeScript中函数与类的概念是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“TypeScript中函数与类的概念是什么”吧!...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作