• Typescript 中根据某个字段判断其他字段是否必传


    背景

    我在使用 Typescript 的时候遇到过这样的一个问题。我有这样的一个组件
    在这里插入图片描述
    前面的两个搜索框是根据参数判断是否要隐藏的,Typescript 的类型定义就是这样的

    type BasicItem = {
    	label: string
    	value: number
    }
    type BrandItem = BasicItem & {}
    
    type PruductionItem = BasicItem & {}
    
    type HeaderPropsType = {
    	hideSearch?: boolean
    	brandOptions: BrandItem[]
    	productionOptions: PruductionItem[]
    }
    function Header(props: HeaderPropsType) {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    如果这样写的话就不能满足要求,我希望是当 hideSearch = true 的时候,brandOptionsproductionOptions 才为必传属性,当他为 false 或者不传的时候,是非必传属性。

    解决方法

    1. 添加默认值

    这个应该是最简单的方法了,如果你不传的话,我给你添加一个空数组不就完事了吗?也不会因为不传而导致在 undefined 上取方法属性而报错

    type HeaderPropsType = {
    	hideSearch?: boolean
    	brandOptions?: BrandItem[]
    	productionOptions?: PruductionItem[]
    }
    function Header({ hideSearch, brandOptions=[], productionOptions=[] }: HeaderPropsType) {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 函数重载

    如果是普通函数的话,可以是用函数重载的方式,大致这样,看起来好像挺复杂的,思想还是比较简单的,就是相当于我定义了几种不同情况的函数的参数和返回值而已。但是这种就不适合用在 React 函数组件上了
    可以点击这里在线体验一下

    type BasicItem = {
    	label: string
    	value: number
    }
    
    type BrandItem = BasicItem & {}
    type ProductionItem = BasicItem & {}
    
    type RequiredType = {
        brandOptions: BrandItem[]
        productionOptions: ProductionItem[]
    }
    
    type OptionalType = Partial<RequiredType>
    type RequiredHideSearch = { hideSearch: true}
    type OptionalHideSearch = { hideSearch?: false}
    
    // 函数重载需要紧跟着实现
    function test(props: OptionalHideSearch & RequiredType): void
    function test(props: RequiredHideSearch & OptionalType): void
    function test(props) {
        return props
    }
    // 这样调用都是可以的
    test({ hideSearch: true })
    test({ brandOptions: [], productionOptions: [] })
    test({ hideSearch: false, brandOptions: [], productionOptions: [] })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3. 类型运算

    这是我比较喜欢的一种方式,当然用默认值是最简单的,也不用去定义那么多类型,但是我总觉得写 typescript,写了那么久,好像就只会这种简单的类型添加,看源码的时候,也很难看懂人家的类型为啥这么写。

    type BasicProps = {
        hideSearch?: boolean
    }
    // 如果 hideSearch = true 就使用 T(就是BasicProps)
    // 否则则使用 T & OptionListType
    // 就是一个简单的三元表达式
    export type HeaderProps<T> = T extends { hideSearch: true }
        ? T
        : T & OptionListType
    
    export type HeaderPropsType<T> = T extends BasicProps ? HeaderProps<T> : {} // 这里最后的 {} 也可以换成别的类型
    function Header<T extends BasicProps>({hideSearch = false}: HeaderPropsType<T>) {}
    
    // 使用组件的时候,就可以这样使用啦,也会有类型提示
    <Header brandOpts={[]} productOpts={[]} />
    <Header hideSearch={true} />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    其实这里也体现了 Typescript 中,interfacetype 的一个区别,interface 就不能进行这些三元运算符的操作

    总结

    其实这个问题我也是问别人的,他们都说我搞那么麻烦干嘛,直接默认值不就搞定了吗?
    在这里插入图片描述
    但是我总觉得多总结总结方法,可以在以后开发的时候,思路多一些,不会只握着手中仅有的知识,止步不前。多探索探索嘛,不然总觉得自己在搬砖,多回头看看以前写的代码,有机会的话,可以总结或者优化一些,这样就不会觉得自己整天都在干相同的事情啦

  • 相关阅读:
    关于强化学习优化粒子群算法的论文解读
    CS5801 HDMI转4K 4lane_DP/eDP方案
    牛客网最新Java面试通关八股文手册,花点耐心每天刷上10道题,挑战一下年薪50W!
    从文字到视频:借助ChatGPT与剪映轻松生成高质量视频(文末送书)
    最新Python深度学习技术进阶与应用
    Policy Gradient with Baseline
    2022年下半年信息系统项目管理师综合知识真题及答案1-20
    根据组件类型与条件动态添加下拉框及选项
    Vulnhub系列靶机-Raven2
    代码随想录算法训练营Day 62| 图论 part02 | 695. 岛屿的最大面积、1020.飞地的数量、130.被围绕的区域
  • 原文地址:https://blog.csdn.net/qq_42501092/article/details/128006501