前端开发通过chatgpt,获得的能力提升,typescript篇(二)

138 阅读2分钟

由于typescript没有找到比较全的基础教程,工作时又会遇到许多typescript问题,因此,typescript是我问chatGPT的高频问题。

询问typescript的作用域

如何全局使用一个typescript类型

在根目录global.d.ts中添加typescript

import { ReqFunc } from '@ali/form-lib';
declare global {
    // 将 ReqFunc 类型添加到全局命名空间中 
   type ReqFunc<T, U> = import('@ali/form-lib').ReqFunc<T, U>;
}

询问typescript报错原因

下面的报错什么意思 Request Error -> TypeError: Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iterator method.

let [a, b] = null;

询问typescript特殊应用

使用typescript实现一个对interface的校验,其中的内容必填一个

interface OptionalFields {
    field1?: string;
    field2?: number;
    field3?: boolean;
    field4?: object; 
}
interface RequiredField { field5: Array<any>; }
type AtLeastOne<T, U = {[K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
type FinalType = RequiredField & AtLeastOne<OptionalFields>; 
// 使用时 let obj: FinalType = { field5: [], field1: "hello" };
// 这是合法的 obj = { field5: [], field2: 42 }; 
// 这也是合法的 obj = { field5: [] };
// 这是不合法的,因为至少需要有一个其他字段

typescript 根据函数入参类型决定出参类型

type CardContentByMode<T extends CardMode> = T extends 'TAG' ? TagCardContent : string[];
type GetCardContentForCreditorRight = <T extends CardMode>( modal: AuctionItemInfo, mode: T, ) => CardContentByMode<T>;

const getCardContentForCreditorRight: GetCardContentForCreditorRight = ( modal, mode, ) => { 
    const { isEmpty } = tools;
    const cardContentArr: string[] = []; 
    const tagArr: string[] = [];
    if (mode === CardMode.TAG) { 
        return { tagArr, cardContentArr } as CardContentByMode<typeof mode>; }
    else { // 抵押物类型 
        return cardContentArr as CardContentByMode<typeof mode>;
    }
};

声明对象类型,对象内有固定规则的键

interface InputProps { 
    size?: SizeType;
    disabled?: boolean;
    status?: InputStatus;
    bordered?: boolean;
    [key: `data-${string}`]: string | undefined;
}

声明对象类型,其中propertyA与propertyB互斥

interface ExclusiveProperties {
    commonProperty: string; 
    propertyA?: string;
    propertyB?: string;
} 
interface ExclusiveA extends ExclusiveProperties {
    propertyA: string;
    propertyB?: never;
} 
interface ExclusiveB extends ExclusiveProperties {
    propertyA?: never;
    propertyB: string; 
} 
type Exclusive = ExclusiveA | ExclusiveB;

询问react组件参数,hook的类型

react onClick中参数的typescript怎么写

import * as React from 'react'; 
class MyComponent extends React.Component {
    handleClick(event: React.MouseEvent<HTMLButtonElement>) { 
    // 这里可以使用 event.currentTarget 访问到 HTMLButtonElement
    }
    render() {
        return <button onClick={(event) => this.handleClick(event as React.MouseEvent<HTMLButtonElement>)}>Click me</button>;
    }
}

一个react组件加入forwardRef后如何定义其类型

interface MyComponentRef {
    doSomething: () => void; 
} 
const MyComponent = forwardRef<HTMLDivElement, Props>((props, ref) => { 
    const divRef = useRef<HTMLDivElement>(null);
    useImperativeHandle(ref, () => ({ 
        doSomething: () => { console.log('do something'); },
        getDivRef: () => { return divRef.current; },
    }));
    return <div ref={divRef}>{props.text}</div>;
});

自定义hooks返回数组时,如何推导数组类型为元组

interface MapSpin {
    centerSpin: boolean;
    leftBottomSpin: boolean;
    isClickMap: boolean;
} 
type LoadingEventHook = () => [ MapSpin, React.Dispatch<React.SetStateAction<MapSpin>> ];
export const useLoadingEvent: LoadingEventHook = () => { 
    const [mapSpin, setMapSpin] = useSetState<MapSpin>({
        centerSpin: false,
        leftBottomSpin: false,
        isClickMap: false, 
    });
    return [mapSpin, setMapSpin];
};