前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript小笔记

TypeScript小笔记

作者头像
19组清风
发布2021-11-15 14:35:21
1K0
发布2021-11-15 14:35:21
举报
文章被收录于专栏:Web Front End

陆陆续续从文档上手TypeScript,发现仍然还是有很多不懂。

比如各种框架的常用类型,ts中内置的常用类型,以及一些容易被忽略和遗忘的点,陆陆续续顺手把他们写到文章中记录起来。

TS

容易忽略的关键字

keyof

The keyof operator takes an object type and produces a string or numeric literal union of its keys

keyof操作符会将一个对象类型(注意这里是类型并不是值)的key组成联合类型返回。

代码语言:javascript
复制
interface IProps {
  name: string;
  count: number;
}
type Ikea = keyof IProps; // Ikea = 'name' | 'count'

function testKeyof(props: Ikea): void { }
复制代码

extends

定义

Tsextends除了用在继承上,还可以表达泛型约束,通过extends关键字可以约束泛型具有某些属性。

其实extends关键字表示约束的时候,就是表示要求泛型上必须实现(包含)约束的属性。

Demo

比如

代码语言:javascript
复制
function loggingIdentity<T>(arg: T): T {
  console.log(arg.length) // Ts语法错误 T可以是任意类型,并不存在length属性
  return arg
}
复制代码

我们定义一个接口来描述约束条件,创建一个包含 .length 属性的接口,使用这个接口和 extends 关键字来实现约束:

代码语言:javascript
复制
interface Lengthwise {
  length: number
}

// 表示传入的泛型T接受Lengthwise的约束
// T必须实现Lengthwise 换句话说 Lengthwise这个类型是完全可以赋给T
function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length) // OK
  return arg
}
复制代码

现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:

代码语言:javascript
复制
loggingIdentity(3);  // Error
复制代码

我们需要传入符合约束类型的值,必须包含必须的属性:

代码语言:javascript
复制
loggingIdentity({length: 10, value: 3}) // OK
复制代码
常用

你可以声明一个类型参数,且它被另一个类型参数所约束。 比如,现在我们想要用属性名从对象里获取这个属性。 并且我们想要确保这个属性存在于对象 obj 上,因此我们需要在这两个类型之间使用约束。

代码语言:javascript
复制
function getProperty<T, K extends keyof T> (obj: T, key: K ) {
  return obj[key]
}

let x = {a: 1, b: 2, c: 3, d: 4}

getProperty(x, 'a') // okay
getProperty(x, 'm') // error
复制代码

表示传入的两个参数,第二个参数被约束成为只能传入objkey类型。

内置类型

ReturnType<Type>

定义

Constructs a type consisting of the return type of function Type.

ResultType<type>接受传入一个函数类型为泛型,返回值为函数的返回类型。

Demo
代码语言:javascript
复制
type T0 = ReturnType<() => string>; // type T0 = string

type T1 = ReturnType<(s: string) => void>; // type T1 = void

复制代码

查阅ReturnType源代码中的类型定义,发现使用了infer类型定义。

infer

定义

infer表示在 extends 条件语句中待推断的类型变量,必须联合extends类型出现。

demo

代码语言:javascript
复制
type ParamType<T> = T extends (...args: infer P) => any ? P : T;


interface User {
  name: string;
  age: number;
}

type Func = (user: User) => void;

type Param = ParamType<Func>; // Param = User
type AA = ParamType<string>; // string
复制代码

其实碰到infer关键字简单的将它理解为一个等待推断的类型(我现在不知道,得根据条件(extends)来判断)就可以了。

重点是:

  1. infer跟随extends成双出现。
  2. infer P表示类型P是一个待推断的类型。(不使用infer直接P会报错)

Record<Keys,Type>

构造一个对象类型,其属性键为Keys,属性值为Type。此实用程序可用于将一种类型的属性映射到另一种类型。

代码语言:javascript
复制
type keys = 'name' | 'title' | 'hello';

interface values {
  name: string;
  label?: number;
}

// Record内置类型可以将 传入的keys联合类型遍历作为key 
// 为每一个key的value赋值为 values从而形成一个全新的对象类型返回
const b: Record<keys, values> = {
  name: {
    name: 'wang',
    label: 1,
  },
  title: {
    name: 'hellp',
  },
  hello: {
    name: 'nihao',
  },
};

复制代码

看看它的源码本质上很简单,就是遍历传入的范型T作为key,将传入的范型value作为值的类型。

Pick<Type, Keys>

Pick的定义很简单,就是从传入的Type中跳出对应的Keys属性,从而返回新的类型。

代码语言:javascript
复制
interface Props {
  name: string;
  label: number;
  value: boolean;
}

type ChildrenProps = Pick<Props, 'name' | 'label'>;
复制代码

Parameters<T>

Parameters<T>用于获得函数的参数类型组成的元组类型

源码中这样定义的

代码语言:javascript
复制
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any 
  ? P : never;
复制代码

Exclude<T,U>

Exclude是进行排除联合类型中的一部分内容,相对于下面的Omit操作符来说Omit是针对于key&value/接口形式的,而Exclude是针对于联合类型来操作的。

代码语言:javascript
复制
let a: string | number;

type CustomType = Exclude<typeof a, string>; // number类型
复制代码

Exclude的原理

type Exclude<T, U> = T extends U ? never : T

传入两个泛型

我们这里用 typeof a 也就是 string | number 去代表 Tstring 属性去代表第二个泛型 U

T extends U 就判断是否string | numberstring, 有string就返回never,就代表将其排除

Omit<T, K>

3.5 版本之后,TypeScript 在 lib.es5.d.ts 里添加了一个 ​Omit<T, K>​ 帮助类型。​Omit<T, K>​ 类型让我们可以从另一个对象类型中剔除某些属性,并创建一个新的对象类型。

比如:

代码语言:javascript
复制
`type User = {`

`id: string;`

`name: string;`

`email: string;`

`};`

`type UserWithoutEmail = Omit<User, "email">;`

`// 等价于:`

`type UserWithoutEmail = {`

`id: string;`

`name: string;`

`};`
复制代码

new关键字

用法

tsnew()表示构造函数类型。

当我们声明一个类的时候,其实声明的是这个类的实例类型和静态类型两个类型。

  • 类的静态类型包含类的所有静态成员和构造函数
  • 类的实例类型包含类的实例方法和属性(包括原型上的实例方法和属性)。

比如

代码语言:javascript
复制
// type: { new(): T }
// 表示函数接受的参数type,是一个对象,这个对象有一个构造函数返回T
// 换句话说type是一个类类型
function factory<T>(type: { new (): T }): T {
	return new type();
}

class Person {
	static myName; // 类的静态属性
	public yourName; // 类的实例属性
}

// 传入的范型Person指类的实例类型
const person = factory<Person>(Person);

复制代码

typeof 类

ts中通过typeof 类可以获得类的类类型,直接使用类作为类型此时使用的是类的实例类型。

代码语言:javascript
复制
let a: Person; // Person表示类的实例类型
a.yourName;
let b: typeof Person; // typeof Person 表示类的类类型
b.myName;
let c: { new (): Person } = Person; // c为构造函数类型,c拥有一个构造函数,也就是new c() 返回的是Person的实例。表示c是Person类。
复制代码

React & TS内置类型

React.ReactNode

源码类型中关于ReactNode的类型定义

代码语言:javascript
复制
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
复制代码

可以看到ReactNode是一个类型别名,他是多种类型组成的联合类型。

其中ReactChildtype ReactChild = ReactElement | ReactText;

ReactPortal定义

代码语言:javascript
复制
 interface ReactPortal extends ReactElement {
        key: Key | null;
        children: ReactNode;
 }
复制代码

所以ReactNode是包含ReactElement类型的联合类型。换句话说ReactElement可以赋给ReactNode,但反过来不可以。

React.element

代码语言:javascript
复制
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }
复制代码

可以看到React.Element类型接受传入两个泛型分别是jsx编译后的vdom对象的props组件本身

返回的仅仅是包含type,props,key的一个Object对象。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年08月31日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TS
    • 容易忽略的关键字
      • keyof
      • extends
    • 内置类型
      • ReturnType<Type>
    • infer
      • 定义
      • demo
    • Record<Keys,Type>
      • Pick<Type, Keys>
        • Parameters<T>
          • Exclude<T,U>
            • Omit<T, K>
              • new关键字
            • 用法
              • typeof 类
              • React & TS内置类型
                • React.ReactNode
                  • React.element
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档