简体   繁体   English

TypeScript 中的部分 function 输入

[英]Partial function input in TypeScript

I want a function to take partial input.我想要一个 function 来获取部分输入。 However, it contains a variable named style whose values can only be outline or fill like:但是,它包含一个名为style的变量,其值只能是outlinefill ,如:

export type TrafficSignalStyle = 'outline' | 'fill'
let style: TrafficSignalStyle

But the problem is when I do Partial<TrafficSignalStyle> , it converts TrafficSignalStyle to 'outline' | 'fill' | undefined但问题是当我执行Partial<TrafficSignalStyle>时,它会将TrafficSignalStyle转换为'outline' | 'fill' | undefined 'outline' | 'fill' | undefined 'outline' | 'fill' | undefined which is not what I want. 'outline' | 'fill' | undefined这不是我想要的。

I want a single function that takes 3 inputs namely style , colors & position & changes only whatever input is passed.我想要一个 function ,它需要 3 个输入,即stylecolorsposition只更改通过的任何输入。 So if I pass style like updateTrafficSignal({ style: e.target.value as TrafficSignalStyle }) then it keeps colors & position the same as it were before.因此,如果我通过updateTrafficSignal({ style: e.target.value as TrafficSignalStyle }) style类的样式,那么它会保持colorsposition与以前相同。

Here's what the related files look like:相关文件如下所示:

types.ts类型.ts

export type TrafficSignalButtons = {
    close: string
    minimize: string
    maximize: string
}

export type TrafficSignalPosition = {
    close: Point
    minimize: Point
    maximize: Point
}

export type TrafficSignalStyle = 'outline' | 'fill'

export type TrafficSignal = {
    style: TrafficSignalStyle
    colors: Array<TrafficSignalButtons>
    position: TrafficSignalPosition
}

export interface IFrameItStore {
    trafficSignal: TrafficSignal
    updateTrafficSignal(trafficSignal: Partial<TrafficSignal>): void
}

FrameItStore.ts FrameItStore.ts

import { action, makeObservable, observable } from 'mobx'

import type { IFrameItStore, TrafficSignal } from './types'

export class FrameItStore implements IFrameItStore {
  trafficSignal: TrafficSignal = {
    style: 'outline',
    colors: [
      {
        close: '#EF4444',
        minimize: '#FBBE25',
        maximize: '#49DE80',
      },
      {
        close: 'black',
        minimize: 'blue',
        maximize: 'orange',
      },
    ],
    position: {
      close: { x: 100 + 20, y: 20 },
      minimize: { x: 100 + 2 * 20, y: 20 },
      maximize: { x: 100 + 3 * 20, y: 20 },
    },
  }

  constructor() {
    makeObservable(this, {
      trafficSignal: observable,
      updateTrafficSignal: action.bound,
    })
  }

  updateTrafficSignal(trafficSignal: Partial<TrafficSignal>) {
    if (trafficSignal.style) this.trafficSignal.style = trafficSignal.style
    if (trafficSignal.colors) this.trafficSignal.colors = trafficSignal.colors
    if (trafficSignal.position) this.trafficSignal.position = trafficSignal.position
  }
}

Options.tsx选项.tsx

import * as React from 'react'
import { observer } from 'mobx-react'

import { useFrameItStore } from './store'
import type { Padding, TrafficSignal, TrafficSignalStyle } from './types'

interface IProps {
    className?: string
}

export const Options = observer((props: IProps) => {
    const frameItStore = useFrameItStore()

    const trafficSignal: TrafficSignal = frameItStore.trafficSignal
    const padding: Padding = frameItStore.padding

    const updateTrafficSignal: (trafficSignal: Partial<TrafficSignal>) => void =
        frameItStore.updateTrafficSignal
    const updatePadding: (padding: Padding) => void = frameItStore.updatePadding

    return (
        <div>
            <h2>Traffic Signal Style:</h2>
            <select
                value={trafficSignal.style}
                onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
                    const style = e.target.value as TrafficSignalStyle
                    updateTrafficSignal({ style })
                }}
            >
                <option value="outline">Outline</option>
                <option value="fill">Fill</option>
            </select>
        </div>
    )
})

However, I get an error saying但是,我收到一条错误消息

 TS2322: Type '(trafficSignal: TrafficSignal) => void' is not assignable to type '(trafficSignal: Partial<TrafficSignal>) => void'.

Types of parameters 'trafficSignal' and 'trafficSignal' are incompatible.参数“trafficSignal”和“trafficSignal”的类型不兼容。 Type 'Partial' is not assignable to type 'TrafficSignal'. “Partial”类型不能分配给“TrafficSignal”类型。 Types of property 'style' are incompatible.属性“样式”的类型不兼容。 Type '"outline" |输入“大纲”| "fill" | “填” | undefined' is not assignable to type 'TrafficSignalStyle'. undefined' 不可分配给类型 'TrafficSignalStyle'。 Type 'undefined' is not assignable to type 'TrafficSignalStyle'.类型“未定义”不可分配给类型“TrafficSignalStyle”。

Which makes sense but how do I pass in only 1 parameter & have that change only that parmeter & not the others.这是有道理的,但我如何只传递 1 个参数并且只改变那个参数而不改变其他参数。

If I remove Partial then I get如果我删除Partial然后我得到

Argument of type '{ style: TrafficSignalStyle; '{ style: TrafficSignalStyle; 类型的参数}' is not assignable to parameter of type 'TrafficSignal'. }' 不可分配给“TrafficSignal”类型的参数。 Type '{ style: TrafficSignalStyle;类型'{风格:交通信号风格; }' is missing the following properties from type 'TrafficSignal': colors, position }' 缺少“TrafficSignal”类型的以下属性:colors、position

Which also makes sense.这也是有道理的。 But still doesn't solve my problem.但仍然没有解决我的问题。

I want a single function to change all 3 params & only 1 will be passed at a time.我想要一个 function 来更改所有 3 个参数,并且一次只传递 1 个。

How do I do it?我该怎么做?

As stated here , there is no such thing available in TypeScript so I passed the params without destructuring & made them optional & it worked.如此处所述, TypeScript中没有这样的东西,所以我在没有解构的情况下传递了参数并将它们设为可选并且它有效。

Here are the changes I made:以下是我所做的更改:

types.ts类型.ts

export interface IFrameItStore {
    updateTrafficSignal(
        style?: TrafficSignalStyle,
        colors?: Array<TrafficSignalButtons>,
        position?: TrafficSignalPosition
    ): void
}

FrameItStore.ts FrameItStore.ts

import { action, makeObservable, observable } from 'mobx'
import type {
  IFrameItStore,
  TrafficSignal,
  TrafficSignalButtons,
  TrafficSignalPosition,
  TrafficSignalStyle,
} from './types'

export class FrameItStore implements IFrameItStore {
  trafficSignal: TrafficSignal = {
    style: 'outline',
    colors: [
      {
        close: '#EF4444',
        minimize: '#FBBE25',
        maximize: '#49DE80',
      },
      {
        close: 'black',
        minimize: 'blue',
        maximize: 'orange',
      },
    ],
    position: {
      close: { x: 100 + 20, y: 20 },
      minimize: { x: 100 + 2 * 20, y: 20 },
      maximize: { x: 100 + 3 * 20, y: 20 },
    },
  }

  constructor() {
    makeObservable(this, {
      trafficSignal: observable,
      updateTrafficSignal: action.bound,
    })
  }
  updateTrafficSignal(
    style?: TrafficSignalStyle,
    colors?: Array<TrafficSignalButtons>,
    position?: TrafficSignalPosition
  ) {
    if (style) this.trafficSignal.style = style
    if (colors) this.trafficSignal.colors = colors
    if (position) this.trafficSignal.position = position
  }
}

Options.tsx选项.tsx

import * as React from 'react'
import { observer } from 'mobx-react'

import { useFrameItStore } from './store'
import type { TrafficSignal, TrafficSignalStyle, IFrameItStore } from './types'

interface IProps {
  className?: string
}

export const Options = observer((props: IProps) => {
  const frameItStore = useFrameItStore()

  const trafficSignal: TrafficSignal = frameItStore.trafficSignal

  const updateTrafficSignal: IFrameItStore['updateTrafficSignal'] =
    frameItStore.updateTrafficSignal

  return (
    <div>
      <h2>Traffic Signal Style:</h2>
      <select
        value={trafficSignal.style}
        onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
          const style = e.target.value as TrafficSignalStyle
          updateTrafficSignal(style)
        }}
      >
        <option value="outline">Outline</option>
        <option value="fill">Fill</option>
      </select>
    </div>
  )
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM