簡體   English   中英

TypeScript 中的部分 function 輸入

[英]Partial function input in TypeScript

我想要一個 function 來獲取部分輸入。 但是,它包含一個名為style的變量,其值只能是outlinefill ,如:

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

但問題是當我執行Partial<TrafficSignalStyle>時,它會將TrafficSignalStyle轉換為'outline' | 'fill' | undefined 'outline' | 'fill' | undefined 'outline' | 'fill' | undefined這不是我想要的。

我想要一個 function ,它需要 3 個輸入,即stylecolorsposition只更改通過的任何輸入。 因此,如果我通過updateTrafficSignal({ style: e.target.value as TrafficSignalStyle }) style類的樣式,那么它會保持colorsposition與以前相同。

相關文件如下所示:

類型.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

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
  }
}

選項.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>
    )
})

但是,我收到一條錯誤消息

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

參數“trafficSignal”和“trafficSignal”的類型不兼容。 “Partial”類型不能分配給“TrafficSignal”類型。 屬性“樣式”的類型不兼容。 輸入“大綱”| “填” | undefined' 不可分配給類型 'TrafficSignalStyle'。 類型“未定義”不可分配給類型“TrafficSignalStyle”。

這是有道理的,但我如何只傳遞 1 個參數並且只改變那個參數而不改變其他參數。

如果我刪除Partial然后我得到

'{ style: TrafficSignalStyle; 類型的參數 }' 不可分配給“TrafficSignal”類型的參數。 類型'{風格:交通信號風格; }' 缺少“TrafficSignal”類型的以下屬性:colors、position

這也是有道理的。 但仍然沒有解決我的問題。

我想要一個 function 來更改所有 3 個參數,並且一次只傳遞 1 個。

我該怎么做?

如此處所述, TypeScript中沒有這樣的東西,所以我在沒有解構的情況下傳遞了參數並將它們設為可選並且它有效。

以下是我所做的更改:

類型.ts

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

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
  }
}

選項.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