【typescript】ts常用类型使用方式汇总

以下代码是以一个echarts图表的demo来展示常用的一些类型定义及使用方式:

包含了以下几个方面:

  • Omit和Pick
  • interface和type
  • 泛型T和extends继承
  • 类型库中取特定属性的类型定义的写法
types.ts
/**
 * OperationReportDTO
 */
export interface OperationReportDTO {
    businessLineId?: number;
    endDate?: string;
    platform?: 'pc' | 'ios' | 'android';
    selectType?: 1 | 2 | 3 | 4;
    startDate?: string;
    /**
     * 时间维度 日1,周2,月3
     */
    timeDimension?: 1 | 2 | 3;
}
EchartsDemo.tsx
import { Panel, Spin } from 'ant-design';
import { useRequest } from '@/hooks';
import { getImSessionData } from '@/services/operationManage/data';
import dayjs from 'dayjs';
import ReactEcharts from 'echarts-for-react';
import React, { useMemo } from 'react';
import { dateFormat1, getZoomConfig, gridConfig, lineConfig } from '../feature/constant';
import { FilterForm } from './FilterForm';

import { getPersonMax } from '@/pages/DataStatistics/feature/utils';
import { OperationReportDTO } from '../types';

interface IPData {
    singles: any[];
    groups: any[];
}

interface IProps<T> {
    data: T & IPData;
    timeDimension: OperationReportDTO['timeDimension'];
}

type FilterValuesType = {
    endDate: string;
    startDate: string;
    timeDimension: OperationReportDTO['timeDimension'];
};

const makeOption = <T extends object>(props: IProps<T>) => {
    const { data, timeDimension } = props;
    if (!data?.singles) {
        return {};
    }
    return {
        color: ['#5590F6', '#44C69D', '#F69055', '#90F655'],
        grid: { ...gridConfig, top: 12 },
        tooltip: {
            trigger: 'axis',
            formatter(params: any) {
                const startDate = params[0]?.name;
                let endDate = '';
                if (timeDimension === 2) {
                    endDate = dayjs(startDate.replace(/\./g, '/')).add(1, 'w').subtract(1, 'd').format(dateFormat1);
                } else if (timeDimension === 3) {
                    endDate = dayjs(startDate.replace(/\./g, '/')).add(1, 'M').subtract(1, 'd').format(dateFormat1);
                }
                const date = endDate ? `${startDate} ~ ${endDate}` : startDate;
                return `
                <div>
                    <div>${date}</div>
                    ${params
                        .map(
                            (p: any) =>
                                `<div style='display:flex;justify-content:space-between;'><span>${p.marker} ${p.seriesName}</span><span style='padding-left:20px;'>${p.value}</span></div>`
                        )
                        .join('')}
                </div>`;
            }
        },
        dataZoom: getZoomConfig(data?.singles),
        xAxis: {
            type: 'category',
            data: data?.singles?.map((item: any) => item.date),
            axisTick: {
                alignWithLabel: true,
                length: 0
            },
            axisLine: {
                lineStyle: {
                    opacity: 0.2
                }
            }
        },
        yAxis: [
            {
                type: 'value',
                axisLabel: {
                    formatter: `{value}`
                },
                splitLine: {
                    lineStyle: {
                        type: 'dashed'
                    }
                },
                max: () => {
                    return getPersonMax(data?.singles?.map((item: any) => Number(item.value || 0)));
                }
            }
        ],
        series: [
            {
                name: '单聊',
                ...lineConfig,
                tooltip: {
                    valueFormatter: (value: string) => {
                        return `${value}`;
                    }
                },
                data: data?.singles?.map((item: any) => {
                    return item.value;
                })
            },
            {
                name: '群聊',
                ...lineConfig,
                lineStyle: {
                    color: '#44C69D',
                    width: 2,
                    type: 'solid'
                },
                tooltip: {
                    valueFormatter: (value: string) => {
                        return `${value}`;
                    }
                },
                data: data?.groups?.map((item: any) => {
                    return item.value;
                })
            }
        ]
    };
};

export const ImSessionDataPanel = () => {
    const [query, setQuery] = React.useState<Pick<OperationReportDTO, 'startDate' | 'endDate' | 'timeDimension'>>();
    const { data: tempData, loading } = useRequest(() => query && getImSessionData(query), {
        manual: false,
        refreshDeps: [query]
    });
    const data = useMemo(() => tempData, [tempData]);

    const handleChange = (values: FilterValuesType) => {
        setQuery({
            ...values
        });
    };

    return (
        <Panel
            title='IM会话'
            extra={
                <FilterForm
                    onChange={handleChange}
                    omitItems={['platform']}
                />
            }
            icon='iconsystem_general_line_3_group-chat|#1ac6ffa6|#1ac6ff'
        >
            <Spin spinning={loading}>
                <div style={{ width: '100%', height: 300, overflow: 'auto', position: 'relative' }}>
                    {data?.singles?.length > 0 && (
                        <ReactEcharts
                            option={makeOption({ data, timeDimension: query?.timeDimension })}
                            notMerge
                            lazyUpdate
                        />
                    )}
                </div>
            </Spin>
        </Panel>
    );
};

import dayjs from 'dayjs';
import _ from 'lodash-es';

export const makeDay7 = () => {
    const date = dayjs(new Date());
    return Array.from({ length: 7 }, (_, index) => {
        return date.subtract(index).format('YYYY-MM-DD');
    });
};

export const makeDefaultData = () => {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    return Array.from({ length: 9 }, (_) => 0);
};

export const makeDayData = () => {
    return Array.from({ length: 7 }, (_, index) => index);
};

export const makeDay8Column = () => {
    return [1, 2, 3, 4, 5, 6, 7, 14, 30].map((item) => ({
        key: item,
        dataIndex: `dataIndex-${item}`,
        title: '一些文本'
    }));
};

export const makeWeek8Column = () => {
    return Array.from({ length: 9 }, (_, index) => ({
        key: index + 1,
        dataIndex: `dataIndex-${index + 1}`,
        title: '一些文本'
    }));
};

export const makeMonth8Column = () => {
    return Array.from({ length: 9 }, (_, index) => ({
        key: index + 1,
        dataIndex: `dataIndex-${index + 1}`,
        title: '一些文本'
    }));
};

export const filterData = <T = any>(data: T[] = [], pageSize: number, current: number): T[] => {
    return _.chunk(data, pageSize)[current - 1];
};

export const isLessDay = <T extends dayjs.Dayjs>(date: [T, T], value: number): boolean => {
    if (!date) {
        return false;
    }
    return dayjs(date[0].valueOf())
        .add(value - 1, 'd')
        .isBefore(date[1]);
};

export const toNumber = (value: number): string => {
    if (!value) {
        return '0';
    }
    if (value < 999) {
        return String(value || 0);
    }
    const reg = /(\d)(?=(?:\d{3})+$)/g;
    return String(value).replace(reg, '$1,');
};

export const getPersonMax = <T extends number>(values: T[]): T => {
    const maxValue = Math.max(...values);
    const step = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000];
    return step.find((s) => s > maxValue) as T;
};

export const formatTimeToHMS = (time: number) => {
    const hour = Math.floor(time / 3600) || 0;
    const minute = Math.floor((time % 3600) / 60) || 0;
    const second = time % 60 || 0;
    const hourStr = hour > 9 ? `${hour}` : `0${hour}`;
    const minuteStr = minute > 9 ? `${minute}` : `0${minute}`;
    const secondStr = second > 9 ? `${second}` : `0${second}`;
    return `${hourStr}:${minuteStr}:${secondStr}`;
};

// 获取使用时长最大值
export const getTimeMax = <T extends number>(values: T[]): T => {
    const maxValue = Math.max(...values);
    const step = [5, 10, 15, 20, 25];
    return step.find((s) => s > maxValue) as T;
};

// 获取使用次数最大值
export const getCountMax = <T extends number>(values: T[]): T => {
    const maxValue = Math.max(...values);
    const step = [5, 10, 50, 100, 500, 1000, 5000, 10000, 50000];
    return step.find((s) => s > maxValue) as T;
};

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值