TS如何获取第三方库未导出的 Type

本文详细介绍了在使用Ant Design的Radio组件时遇到的onChange事件类型问题,以及如何通过TypeScript的typeof和Parameters等工具类型推导出正确的事件参数类型。同时,提供了在第三方库未导出类型时的解决方案,包括直接使用typeof推导和参数解构来获取函数参数类型。文章强调了解决这类问题的重要性,以提升开发效率。
摘要由CSDN通过智能技术生成

在使用 antd 组件的时候,同事遇到一个问题,Radio 组件的 onChange 事件处理函数,传递的参数是一个事件对象,无法推导类型:

import { Radio } from "antd";
import * as React from "react";

type Props = {
	name: string;
}

const HelloWorld: React.FC<Props> = ({ name }) => {
    const [value, setValue] = React.useState(0);
    // 这边的形参 e 会提示隐式 any
    const onChange = (e) => {
        setValue(e.target.value);
    }
    return (
        <Radio.Group onChange={onChange} value={value}>
            <Radio value={1}>A</Radio>
            <Radio value={2}>B</Radio>
        </Radio.Group>
    )
}

先尝试了一下 React 的事件类型声明:

const onChange = (e: React.FormEvent<HTMLInputElement>) => {
	setValue(e.target.value);
}

const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
	setValue(e.target.value);
}

试验之后发现两种方法都不行,看来 antd 内部应该是对原生事件类型进行了封装,导致和 React 合成事件无法匹配上了。

最后同事通过导入 RadioChangeEvent 解决问题:

import { RadioChangeEvent } from "antd/lib/radio";

const onChange = (e: RadioChangeEvent) => {
	setValue(e.target.value);
}

那么这边有一个问题,如果第三方库没有导出 Type ,如何获取到类型呢?这边提供两种方案。

1. 使用 typeof 推导

可以使用 typeof 推导出 type :

import { Radio } from "antd";

// 使用 typeof 推导出 Radio.Group 的类型
// 使用 React.ComponentProps 获取到 props 的类型
type RadioGroupProps = React.ComponentProps<typeof Radio.Group>;
// 使用 Pick 工具类型过滤出 onChange 类型
type EventProps = Pick<RadioGroupProps, "onChange">;
// 获取 onChange 类型
// type ChangeEvent = ((e: RadioChangeEvent) => void) | undefined
type ChangeEvent = EventProps["onChange"];

const onChange:ChangeEvent = (e) => {
	setValue(e.target.value);
}

这样就基本上可以了。但是如果想直接获取到参数的类型呢?可以使用 TS 提供的 Parameters 获取到函数参数类型:

import { Radio } from "antd";

type RadioGroupProps = React.ComponentProps<typeof Radio.Group>;
type ChangeEvent = RadioGroupProps["onChange"];
// 上一步获取到的类型是包含 undefined 的联合类型
// 需要先把 undefined 过滤掉
// 最后得到一个包含参数类型的元组
type ChangeFnParams = Parameters<NonNullable<ChangeEvent>>[0];

const onChange = (e: ChangeFnParams) => {
	setValue(e.target.value);
}

此外 TS 还提供了 ReturnType 工具类,可以获取到函数的返回类型:

type IsArray = typeof Array.isArray;
type Return = ReturnType<IsArray>; // type Return = boolean

type ParseInt = typeof parseInt;
type Return = ReturnType<ParseInt>; // type Return = number

type MathMax = typeof Math.max;
type Return = ReturnType<MathMax>; // type Return = number

2. 参数解构

这种方法相信很多同学都用过,先对参数解构,然后声明解构之后的参数类型即可:

type ChangeEvent = {
	target: HTMLInputElement;
}

const onChange = ({ target }: ChangeEvent) => {
	setValue(target.value);
}

上面这样等于还套了一层,可以直接解构到 value

type ChangeEvent = {
	target: {
		value: string;
	}
}

const onChange = ({ target: { value } }: ChangeEvent) => {
	setValue(value);
}

参考

掌握 TS 这些工具类型,让你开发事半功倍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值