内容简介:TypeScript 2.9 版本中添加了一个在 NodeJS 中,我们通常会导入一些当重写为 TypeScript 之后,仅仅是将
TypeScript 2.9 版本中添加了一个 resolveJsonModule
编译选项,它允许我们在 TypeScript 模块中导入 JSON 文件。
在 NodeJS 中,我们通常会导入一些 .json
文件,如下所示:
// config.json { "debug": true } 复制代码
const config = require('./config.json'); config.debug === true // true 复制代码
当重写为 TypeScript 之后,仅仅是将 require
语法改写成 ES Module,而不做其他修改,TypeScript 将会抛出错误:
import config from './1.json'; // Error: Cannot find module './1.json' 复制代码
这是由于在默认情况下,相对路径导入模块时,TypeScript 只识别 .ts/tsx
文件模块。如果你使用的是 TypeScript 2.9 前的版本,你可能会用以下方式:
declare module '*.json'; 复制代码
但是它也只 decalre
了一个模块,模块内容还是 any,也就是无法得到一些代码提示(无法得到有关键值对信息)。
TypeScript 2.9 添加 resolveJsonModule
编译选项,很好的解决了这个问题:
unknown 替代 any
使用 TypeScript 的过程中,难免会有使用 any 的情况,这个时候倒不如换个方式,使用 unknown 试试。
unknown 最早出现在此 PR 中,随 3.0 一起发布。它被认为是安全版的 any,与 any 不同的是,unknown 仅能赋值给 any、unknown 类型,以及 unknown 上不存在任何属性与方法。
let a: any = 10; // 任何类型都能赋值给 any let u: unknown = 10; // 与 any 一样,任何类型都能赋值给 unknown let s1: string = a; // any 能赋值给任何类型 let s2: string = u; // 不能把 unknown 赋值给除 any、unknow 以外的其他类型 a.method(); // any 上有任意的属性和方法 u.method(); // unknown 没有被断言到一个确切类型之前,不具备任何属性和方法 复制代码
当然,unknown 也能被断言,或是类型缩小至一个指定的范围:
const name: unknown = 'hello'; const str = name as string; // unknown 断言为 string 类型 const oStr = str.toUpperCase(); // HELLO function doSome(x: unknown) { if (typeof x === 'string') { // 在这个块中,TypeScript 知道 `x` 的类型必须是 `string` console.log(x.subtr(1)); // Error: 'subtr' 方法并没有存在于 `string` 上 console.log(x.substr(1)); // ok } if (x instanceof Date) { // x 是 Datee 类型 console.log(x.toISOString()); // ok } } 复制代码
也可以使用自定义保护类型:
function isNumberArray(value: unknown): value is number[] { return ( Array.isArray(value) && value.every(element => typeof element === "number") ); } const unknownValue: unknown = [15, 23, 8, 4, 42, 16]; if (isNumberArray(unknownValue)) { // unknownValue 类型是 number[] const max = Math.max(...unknownValue); console.log(max); } 复制代码
对于 unknown 的使用,官方推荐的用法是:
我们经常需要在 TypeScript 中描述功能最少的类型。这对于那些「希望是任何类型,但是在使用之前必须执行某种类型检查」非常有用,它强制使用者安全性的思考它返回的值。
此外,在即将发布的 3.5 版本中,泛型参数的隐式类型由 {}
类型,变成 unknown
,即,在 3.5 以下版本时,可以:
function test<T>(params: T) { return params.toString(); // ok } 复制代码
3.5 版本以上,这将会报错:
function test<T>(params: T) { return params.toString(); // ERROR: Property 'toString' does not exist on type 'T'. } 复制代码
你可以这么做来修复它:
function test<T extends {}>(params: T) { return params.toString(); // ok } 复制代码
const 断言
当声明一个可变变量或者属性时,TypeScript 通常会扩展变量类型,来确保我们在不编写显示类型时,可以赋值内容:
let x = 'hello'; // x 的类型是 string // 可以重新赋值 x = 'world'; 复制代码
你也可以声明一个字面量类型,在接下来将不能被重新赋值:
let x: 'hello' = 'hello'; // x 的类型是 hello // 或者是 x = 'hello' as 'hello' // error,不能重新赋值 x = 'world'; 复制代码
这种方式似乎很极端,但在某些情况下,却是很有用:
interface Test { pos: 'left' | 'right' | 'top' | 'bottom' } function func() { // 可能是经过一系列计算得到的值 return { pos: 'left' } } // Error: TypeScript 将会把 func 推断为 { pos: string },而不是 { pos: 'left' } let t: Test = func(); 复制代码
你可以通过字面量解决这个问题:
function func() { // 可能是经过一系列计算得到的值 return { pos: 'left' as 'left' } } // Error: TypeScript 将会把 func 推断为 { pos: string },而不是 { pos: 'left' } let t: Test = func(); 复制代码
随着数据结构逐渐变得复杂,这种方式变得越来越麻烦,const 断言的出现,正是为了解决这样的问题。
function func() { // 可能是经过一系列计算得到的值 return { pos: 'left' } as const } // ok let t: Test = func(); 复制代码
使用 const 断言时:
- 表达式中的字面量类型不应该被扩展(如,不应该从字面量类型
hello
到string
类型) - 对象字面量类型属性只读
- 数组字面量成为 readonly tuples
即:
let obj = { x: 10, y: ['hello', 2'], z: { a: { b: 'top' } } } as const; // obj 的类型是: // { // readonly x: 10; // readonly y: readonly ["hello", "2"]; // z: { // a: { // readonly b: "top"; // }; // }; // } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法:C语言实现
塞奇威克 / 霍红卫 / 机械工业出版社 / 2009-10 / 79.00元
《算法:C语言实现(第1-4部分)基础知识、数据结构、排序及搜索(原书第3版)》细腻讲解计算机算法的C语言实现。全书分为四部分,共16章。包括基本算法分析原理,基本数据结构、抽象数据结构、递归和树等数据结构知识,选择排序、插入排序、冒泡排序、希尔排序、快速排序方法、归并和归并排序方法、优先队列与堆排序方法、基数排序方法以及特殊用途的排序方法,并比较了各种排序方法的性能特征,在进一步讲解符号表、树等......一起来看看 《算法:C语言实现》 这本书的介绍吧!