TS中的一些关键词总结(文末送书)

TS中的一些关键词总结

最近一直在写TS,偶尔会遇到一些本身以前没见过的一些符号或者关键词,就随手记录下来,本篇文章就是对这段时间遇到的进行了总结。html

目录概览

  • TS中的一些符号git

    • ! 断言操做符
    • ?. 链判断运算符
  • TS中的一些关键词github

    • type
    • interface
    • typeof
    • keyof
    • in
  • TS中的一些内置类型web

    • Partial<T> 将类型的属性变成可选
    • Required<T>将类型的属性变成必选
    • Pick 从某个类型中挑出一些属性出来
    • Record
    • Mutable<T> 将类型的属性变成可修改
    • Readonly<T> 类型的属性变成只读
    • ReturnType 用来获得一个函数的返回值类型

下面的一些例子均可以在 TypeScript Playground[1] 中进行尝试。左侧是TS,右侧是编译后的JS。typescript

TS中的一些符号

! 断言操做符

! 的做用是断言某个变量不会是 null/undefined,告诉编辑器中止报错。segmentfault

const obj = {
    name'牧码的星星'
}
const a = obj!.name; // 假设 obj是你从后端获取的获取

肯定 obj.name 必定是存在的且不是null/undefined,使用! 只是消除编辑器报错,不会对运行有任何影响。后端

属性或者参数中使用 !,表示强制解析(告诉 typescript 编译器,这里必定有值); 变量后使用 !: 表示类型推荐排除 null/undefined。微信

?. 链判断运算符

const orderId = response.result.data.orderId;

上面这种写法,很容易出现这种问题 orderId is undefined,稍微有些经验的咱们立马就能想到,确定是代码中 response.result.datanull 或者 undefined ,这样,你确定获取不到 orderId。因此经验丰富的咱们在遇到获取层级比较多的对象的时候,通常都是像下面这样写。app

// 正确的写法
const orderId = (response
  && response.result
  && response.result.data
  && response.result.data.orderId) || '';

咱们可使用 ?. 来简化上面的代码。框架

const orderId = response?.result?.data?.orderId || '';

上面代码使用了?.运算符,直接在链式调用的时候判断,左侧的对象是否为null或undefined。若是是的,就再也不往下运算,而是返回undefined。

?. 支持以下语法

obj?.prop // 对象属性
obj?.[expr] // 对象属性
arr?.[index] // 获取数据中 index 下标对应的值
func?.(...args) // 函数或对象方法的调用

?.&& 的区别

TS中的一些关键词

type 类型别名用来给一个类型起个新名字

type SetUser = (name: string, age: number) => void;

类型别名经常使用于联合类型(联合类型表示取值能够为多种类型中的一种),好比常见的以下写法

type UploadType = 'drag' | 'select';

interface

interface 和 type 的用法其实差很少,interface 也是用来定义类型的

interface SetUser = {
    (name: string, age: number) => void;
}

type和interface的区别

都支持拓展,可是语法不一样

interface Name { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}
type Name = { 
  name: string; 
}
type User = Name & { age: number  };

typeof 能够获取一个变量的声明类型

在 JavaScript 中, typeof 能够判断一个变量的基础数据类型, 在 TS 中,它还能够获取一个变量的声明类型

const obj = { a'1' };
type Foo = typeof obj; 
// type Foo = { a: string }

keyof 能够获取一个对象接口的全部 key 值

type Obj = { a: string; b: string }
type Foo = keyof obj;
// type Foo = 'a' | 'b';

in 能够遍历枚举类型

type Keys = 'a' | 'b' | 'c';
type Obj = { 
    [ T in Keys]: string;
}
// in 遍历 Keys,并为每一个值赋予 string 类型

// type Obj = {
//     a: string,
//     b: string,
//     c: string
// }

TS中一些内置的类型

官方文档:https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt

用到了上面提到的一些关键词

Partial<T> 将类型的属性变成可选

功能是将类型的属性变成可选,注意这是浅Partial

type Partial<T> = { 
    [P in keyof T]?: T[P] 
};

举例说明

interface UserInfo {
    id: string;
    name: string;
}

// error:Property 'id' is missing in type '{ name: string; }' but required in type 'UserInfo'
const xiaoming: UserInfo = {
    name'xiaoming'
}

使用  Partial<T>

type NewUserInfo = Partial<UserInfo>;

const xiaoming: NewUserInfo = {
    name'xiaoming'
}

这个  NewUserInfo 就至关于

interface NewUserInfo {
    id?: string;
    name?: string;
}

可是 Partial<T> 有个局限性,就是只支持处理第一层的属性,若是个人接口定义是这样的

interface UserInfo {
    id: string;
    name: string;
    fruits: {
        appleNumber: number;
        orangeNumber: number;
    }
}

type NewUserInfo = Partial<UserInfo>;

// Property 'appleNumber' is missing in type '{ orangeNumber: number; }' but required in type '{ appleNumber: number; orangeNumber: number; }'.
const xiaoming: NewUserInfo = {
    name'xiaoming',
    fruits: {
        orangeNumber1,
    }
}

能够看到,第二层之后就不会处理了,若是要处理多层,就能够本身经过  Conditional Types[2]

DeepPartial

type DeepPartial<T> = {
     // 若是是 object,则递归类型
    [U in keyof T]?: T[U] extends object
      ? DeepPartial<T[U]>
      : T[U]
};

type PartialedWindow = DeepPartial<Window>; // 如今window 上全部属性都变成了可选啦

Required 将类型的属性变成必选

type Required<T> = { 
    [P in keyof T]-?: T[P] 
};

其中 -? 是表明移除 ? 这个 modifier 的标识。再拓展一下,除了能够应用于 ? 这个 modifiers ,还有应用在 readonly ,好比 Readonly<T> 这个类型

type Readonly<T> = {
    readonly [p in keyof T]: T[p];
}

Pick 从某个类型中挑出一些属性出来

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
interface UserInfo {
    id: string;
    name: string;
}
type NewUserInfo = Pick<UserInfo, 'name'>; // {name: string;}

能够看到 NewUserInfo 中就只有个 name 的属性了。

Record

能够得到根据 K 中全部可能值来设置 key 以及 value 的类型

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

举个例子

type CurRecord = Record<'a' | 'b' | 'c', UserInfo>; // { a: UserInfo; b: UserInfo; c: UserInfo; }

Mutable<T> 将类型的属性变成可修改

功能是将类型的属性变成可修改,这里的 -指的是去除。-readonly 意思就是去除只读,也就是可修改啦。

type Mutable<T> = {
  -readonly [P in keyof T]: T[P];
};

Readonly<T> 类型的属性变成只读

type Readonly<T> = { 
    readonly [P in keyof T]: T[P] 
};

ReturnType 用来获得一个函数的返回值类型

type ReturnType<T extends (...args: any[]) => any> = T extends (
  ...args: any[]
) => infer R
  ? R
  : any;

infer在这里用于提取函数类型的返回值类型。ReturnType<T> 只是将 infer R 从参数位置移动到返回值位置,所以此时 R 便是表示待推断的返回值类型。

下面的示例用ReturnType获取到 Func 的返回值类型为 string,因此,foo 也就只能被赋值为字符串了。

type Func = (value: number) => string;

const foo: ReturnType<Func> = "1";

更多参考TS - es5.d.ts[3]

参考

  • 细数 TS 中那些奇怪的符号 [4]
  • TypeScript中高级应用与最佳实践 [5]
  • TS 中的内置类型简述 [6]
  • TypeScript 的工具类型 [7]
  • 深刻理解 TypeScript [8]

参考资料

[1]

TypeScript Playground: https://www.typescriptlang.org/play

[2]

Conditional Types: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

[3]

TS - es5.d.ts: https://github.com/microsoft/TypeScript/blob/master/src/lib/es5.d.ts#L1431

[4]

细数 TS 中那些奇怪的符号: https://segmentfault.com/a/1190000023943952

[5]

TypeScript中高级应用与最佳实践: https://juejin.im/post/6844903904140853255#heading-9

[6]

TS 中的内置类型简述: https://github.com/whxaxes/blog/issues/14

[7]

TypeScript 的工具类型: https://zhuanlan.zhihu.com/p/78180787

[8]

深刻理解 TypeScript: https://jkchao.github.io/typescript-book-chinese/


送书活动

为了感谢各位小星星们一直以来对 【牧码的星星】的大力支持和确定,如今推出以下送抽奖送书活动。

奖项设置

《TypeScript 项目开发实战》 1 本

本书是一本TypeScript进阶实践指南,经过 9 个实用项目,详细讲解如何使用TypeScript 3.0和不一样的JavaScript框架开发高质量的应用程序。书中不只介绍TypeScript的核心概念与技术,还涵盖AngularReact的一些新功能,以及GraphQL、微服务和机器学习等相关的新技术。

同时可点击下方连接进行购买~

参与方式

参与方式很简单,关注 【牧码的星星】公众号回复 666, 参与抽奖

截止时间

  • 活动截止 2020年9月21号 中午12:00
  • 兑奖截止 2020年9月23号 中午12:00

舒适提示

请在开奖前添加个人微信,不然将没法领取奖品。

  

本文分享自微信公众号 - 牧码的星星(gh_0d71d9e8b1c3)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索