首页 > 解决方案 > 使用打字稿和默认值解构嵌套参数

问题描述

如果我在 javascript 中有以下内容:

//deconstructed
({ theme: { colors: { border = '#cccccc' } = {} } = {} } => border)

//Creating similar with nested params
//Optional Chaining
props?.theme?.colors?.border ?? '#cccccc' 

//bog standard js
props.theme && props.theme.colors ? props.theme.colors.border : '#cccccc'

这是我到目前为止所取得的成果typescript

(props:Props, { theme: { colors: { border = '#cccccc' } = {} } = {} }: { theme: Object }) => border

但这会因以下原因而失败:

TypeScript error in /var/www/poc/src/components/text-input/text-input.tsx(53,17):
No overload matches this call.
  Overload 1 of 3, '(first: TemplateStringsArray | CSSObject, ...interpolations: SimpleInterpolation[]): FlattenSimpleInterpolation', gave the following error.
    Argument of type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is not assignable to parameter of type 'SimpleInterpolation'.
      Type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is missing the following properties from type 'FlattenSimpleInterpolation': concat, join, slice, indexOf, and 17 more.
  Overload 2 of 3, '(first: TemplateStringsArray | CSSObject | InterpolationFunction<ThemeProps<any>>, ...interpolations: Interpolation<ThemeProps<any>>[]): FlattenInterpolation<...>', gave the following error.
    Argument of type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is not assignable to parameter of type 'Interpolation<ThemeProps<any>>'.
      Type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is not assignable to type 'InterpolationFunction<ThemeProps<any>>'.
  Overload 3 of 3, '(first: TemplateStringsArray | CSSObject | InterpolationFunction<ThemedStyledProps<Props, any>>, ...interpolations: Interpolation<...>[]): FlattenInterpolation<...>', gave the following error.
    Argument of type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is not assignable to parameter of type 'Interpolation<ThemedStyledProps<Props, any>>'.
      Type '(props: Props, { theme: { colors: { border } } }: { pretty: Object; }) => any' is not assignable to type 'InterpolationFunction<ThemedStyledProps<Props, any>>'.  TS2769

    51 | /* css border variants (this is an example of splitting up styles a bit more than the example in StyledLabel) */
    52 | const normalBorder = css`
  > 53 |     1px solid ${(props:Props, { theme: { colors: { border = '#cccccc' } = {} } = {} }: { theme: Object }) => border};
       |                 ^
    54 | `;
    55 | 
    56 | const errorBorder = css`

标签: javascripttypescriptecmascript-6

解决方案


这是具有默认值的解构参数的工作示例:

const myFn = ({ theme: { colors: { border = '#cccccc' } = {} } = {} } = {}) => border

myFn() // #cccccc
myFn({}) // #cccccc
myFn({ theme: {} }) // #cccccc
myFn({ theme: { colors: {} } }) // #cccccc
myFn({ theme: { colors: { border: '#000000' } } }) // #000000

// Not sure, how your `props` are related to the theme object, so I omitted them here

使用深度嵌套的结构,解构赋值确实变得难以阅读。当您为显式类型myFn或参数提供显式类型时,它甚至变得更加复杂:

type Themeable = {
    theme?: {
        colors?: {
            border?: string
        }
    }
}

const myFn = ({ theme: { colors: { border = '#cccccc' } = {} } = {} }: Themeable = {}) 
  => border 

TS 文档建议使它们尽可能简单或手动编写作业以获得更好的可读性:

谨慎使用解构。正如前面的例子所展示的,除了最简单的解构表达式之外,任何东西都是令人困惑的。对于深度嵌套的解构尤其如此,即使没有重命名、默认值和类型注释,也很难理解。尽量保持解构表达式小而简单。您始终可以编写解构将自己生成的分配。

代码示例


推荐阅读