Definitelytyped: @ рдкреНрд░рдХрд╛рд░/рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЗ рд▓рд┐рдП рдкрд┐рдХ рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░

рдХреЛ рдирд┐рд░реНрдорд┐рдд 25 рдЬреБрд▓ре░ 2017  ┬╖  53рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: DefinitelyTyped/DefinitelyTyped

рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ Pick рдХрд╛ рдЙрдкрдпреЛрдЧ setState рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдХреБрдВрдЬреА рдХреЗ рд▓рд┐рдП undefined рд▓реМрдЯрдиреЗ рдкрд░ рдЬреЛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХреБрдВрдЬреА рдХреЛ рд░рд┐рдПрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, Pick рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЕрдиреНрдп рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВред рдПрдХ рдХреЗ рд▓рд┐рдП, рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реЗрд╡рд╛ рдХрд╛ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдмреЗрдХрд╛рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕реНрд╡рдд: рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП Pick рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рдЖрдк рдкреВрд░реНрдгрддрд╛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ рддреЛ Pick рдХреЗ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдЕрднреА рддрдХ рд╡рд╣ рдХреБрдВрдЬреА рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдХреЙрд▓рдмреИрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде setState рд▓рд┐рдЦрддреЗ рд╕рдордп рд╕рдорд╕реНрдпрд╛рдПрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЦрд░рд╛рдм рд╣реЛрддреА рд╣реИрдВ:

  1. рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдЖрдкрдХреЗ рдкрд╣рд▓реЗ return рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╕реЗ рд▓реА рдЧрдИ рд╣реИ; рдпрджрд┐ рдЖрдк рдЕрдкрдиреЗ рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдХреБрдВрдЬреА рдирд╣реАрдВ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рддрд░реНрдХ рдореЗрдВ рдирд╣реАрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд┐рдирд╛ рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ never рдкрд░ рд░реАрд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдПред рдПрдХрд╛рдзрд┐рдХ рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд▓рд┐рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд╡реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреБрдВрдЬреА рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрд╣реАрдВ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд░рд┐рдЯрд░реНрди рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП if (state.busy) { return } )ред

    • рдпрд╣ рд╣рдореЗрд╢рд╛ рдПрдХ рдкреНрд░рд╕рд╛рд░ (рдЬреИрд╕реЗ this.setState(input => ({ ...input, count: +input.count + 1 })) ) рдореЗрдВ рдЗрдирдкреБрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмреЗрдорд╛рдиреА рд╣реИ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдмрдбрд╝реЗ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ deoptimization рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ setState рдХреЙрд▓рдмреИрдХ рдХреЗ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░реЗрдЧрд╛ Object.assign ред

  2. рдпрджрд┐, рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЖрдк рд▓реМрдЯ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рдЗрдирдкреБрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИ, рддреЛ Pick рдЕрдкрдиреА рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП never рдЪрдпрди рдХрд░реЗрдЧрд╛, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ _anything_ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдПрдЧреАред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдореМрдЬреВрджрд╛ рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реА рдХреБрдВрдЬрд┐рдпрд╛рдВ рднреА any рдХреЛ рдПрдХ рдореВрд▓реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИрдВ - рдпрджрд┐ рдпрд╣ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рд╕рд┐рд░реНрдл Pick рдПрдб рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕реЗ {} рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ
  3. рдпрджрд┐ never рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдКрдкрд░ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рд╕реА рднреА рдХрд╛рд░рдг рд╕реЗ, рдХреЙрд▓рдмреИрдХ рддрд░реНрдХ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ setState рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдлреЙрд░реНрдо рдХреЗ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ; рдЗрд╕ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ рдХреЙрд▓рдмреИрдХ рдХреЗ рддрд░реНрдХреЛрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ any рдХреЗ рдмрдЬрд╛рдп {} ред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдИ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддреНрд░реБрдЯрд┐ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИред
interface State {
  count: string // (for demonstration purposes)
}

class Counter extends React.Component<{}, State> {
  readonly state: Readonly<State> = {
    count: '0'
  }

  render () {
    return React.createElement('span', { onClick: this.clicked }, this.state.count)
  }

  private readonly clicked = () => {
    this.setState(input => ({
      count: +input.count + 1 // not a type error
      // the setState<never>(input: Pick<State, never>) overload is being used
    }))
  }
}

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, Pick рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдХреБрдЫ рдЕрд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЧреИрд░-рдХреЙрд▓рдмреИрдХ рд░реВрдк рдореЗрдВ setState рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдХреЙрд▓рдмреИрдХ рдлреЙрд░реНрдо рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рддрд┐-рдЙрддреНрдкрд╛рджрдХ рд╣реИ; рдЬрд╣рд╛рдВ рдпрд╣ рди рдХреЗрд╡рд▓ undefined рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдЗрдЪреНрдЫрд┐рдд рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдмрд▓реНрдХрд┐ рдХреЙрд▓рдмреИрдХ рдХреЗ рдЗрдирдкреБрдЯ рдпрд╛ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХреЛ рдЕрдХреНрд╖рдо рднреА рдХрд░рддрд╛ рд╣реИред

рд╢рд╛рдпрдж рдЗрд╕реЗ рдХрдо рд╕реЗ рдХрдо рдХреЙрд▓рдмреИрдХ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП Partial рдмрджрд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ undefined рдорд╛рди рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рдирд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдкреБрд░рд╛рдиреА рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рд╣рд╛рд▓рд┐рдпрд╛ "рдлрд┐рдХреНрд╕" рдЕрдм рдореЗрд░реЗ рд▓рд┐рдП setState() рдХреЙрд▓рдмреИрдХ рдХреЗ рднреАрддрд░ рдХрдИ рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдЯрд╛рдЗрдкрдкреНрд░рддрд┐: 2.6.2 рд╕рднреА "рд╕рдЦреНрдд" рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде "рд╕рдЦреНрдд рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░" рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рдХреНрд╖рдо
рдкреНрд░рдХрд╛рд░/рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛: резрем.реж.рейреж

рдХреЛрдб рдЙрджрд╛рд╣рд░рдг:

interface TestState {
    a: boolean,
    b: boolean
}

class TestComponent extends React.Component<{}, TestState> {
    private foo(): void {
        this.setState((prevState) => {
            if (prevState.a) {
                return {
                    b: true
                };
            }

            return {
                a: true
            };
        });
    }
}

рд╕рдВрдХрд▓рдХ рддреНрд░реБрдЯрд┐:

error TS2345: Argument of type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to parameter of type '((prevState: Readonly<TestState>, props: {}) => Pick<TestState, "b"> & Partial<TestState>) | (Pick<TestState, "b"> & Partial<TestState>)'.
  Type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to type 'Pick<TestState, "b"> & Partial<TestState>'.
    Type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to type 'Pick<TestState, "b">'.
      Property 'b' is missing in type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }'.

522         this.setState((prevState) => {
                          ~~~~~~~~~~~~~~~~

рд╕рднреА 53 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рд░реЛрдЪрдХ рдорд╛рдорд▓рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рд╕рд╛рдордиреЗ рд▓рд╛ рд░рд╣реЗ рд╣реИрдВред

рдХрд┐рд╕реА рд░рд╛рдп рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрджреНрдз рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдореБрдЭреЗ рдЗрд╕рдХреЗ рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕реЛрдЪрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред

рдПрдХ рдмрд┐рдВрджреБ рдкрд░ @ahejlsberg рд╡реИрдХрд▓реНрдкрд┐рдХрддрд╛ рдХреЛ | undefined рд╕реЗ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░ foo?: string рдХрд╛ рдЕрд░реНрде рд╣реЛрдЧрд╛ foo рдпрд╛ рддреЛ рдкрд░реЗрд╢рд╛рди рд╣реИ рдпрд╛ рдпрд╣ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИред

рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкрдврд╝рддреЗ рд╕рдордп, рдЕрдВрддрд░ 99.9% рд╕рдордп рдХреЗ рд▓рд┐рдП рдЕрдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ Partial<> рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдВрддрд░ рдмреЗрддрд╣рд╛рд╢рд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдПрдХ рдмреНрд░реЗрдХрд┐рдВрдЧ рднрд╛рд╖рд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╣реИ рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ 3.0 рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП рдпрд╛ рдЗрд╕реЗ рдзреНрд╡рдЬ рдХреЗ рдкреАрдЫреЗ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЕрдЧрд░ рд╣рдордиреЗ рдХрд╣рд╛ рдерд╛ рдХрд┐ рдкрд░рд┐рд╡рд░реНрддрди, Partial<> рдореЗрд░реА рд╡рд░реНрддрдорд╛рди рд╣рдардзрд░реНрдорд┐рддрд╛ рдХреЗ рдмрдЬрд╛рдп рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдВрдд рдЙрдкрдпреЛрдЧреА рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рджреЗрдЦрддреЗ рд╣реА рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджреЗрддрд╛ рд╣реИред

@ahejlsberg рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдПрдХ рд╡реНрдпрд╕реНрдд рд╡реНрдпрдХреНрддрд┐ рд╣реИрдВ, рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдХрд┐рддрдирд╛ рдХрдард┐рди рд╣реЛрдЧрд╛? рдРрд╕рд╛ рд╣реИ рдХрд┐ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдПрдХ рдирд┐рд╣рд┐рдд рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдореВрд▓реНрдп рдирд╣реАрдВ рд╣реИ?

рдареАрдХ рд╣реИ, рдЖрдЬ рд╕реБрдмрд╣ рдХреБрдЫ рд╕рдордп рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╕рдорд╕реНрдпрд╛ рдХреЗ рдХреБрдЫ "рд╕рдорд╛рдзрд╛рди" рджрд┐рдЦрд╛рдИ рджреЗ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рдХреБрдЫ рдмрд╣реБрдд рднрд╛рд░реА рджреБрд╖реНрдкреНрд░рднрд╛рд╡ рд╣реИрдВред

1. рд╡реИрдХрд▓реНрдкрд┐рдХрддрд╛ рдмрджрд▓реЗрдВ ( interface State { foo?: string } ) рдорддрд▓рдм рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

рдЙрджрд╛рд╣рд░рдг:

interface State {
  foo: string;
  bar: string;
}

const bleh: Partial<State> = { foo: "hi" }; // OKAY
const bleh: Partial<State> = { foo: undefined; } // BREAK

рдпрд╣ рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░реЗрдЧрд╛ рдФрд░ рд╣рдореЗрдВ Partial<> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, 98% рдорд╛рдорд▓реЗ рдХреЗ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реЛрдиреЗ рдХреА рдХреАрдордд рдкрд░ред рдпрд╣ рджреБрдирд┐рдпрд╛ рдХреЛ рддреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ рдЗрд╕рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ 3.x рддрдХ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдФрд░ рдЖрдо рддреМрд░ рдкрд░, рдмрд╣реБрдд рдХрдо рдкреБрд╕реНрддрдХрд╛рд▓рдп/рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдмрдирд╛рдо рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗ рдмреАрдЪ рднреЗрдж рдХреА рдкрд░рд╡рд╛рд╣ рдХрд░рддреЗ рд╣реИрдВред

2. рдмрд╕ рдЖрдВрд╢рд┐рдХ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВ

рдЙрджрд╛рд╣рд░рдг:

interface State {
  foo: string;
  bar: string;
}

setState(prevState => {foo: "hi"}); // OKAY
setState(prevState => {foo: undefined}); // OKAY BUT BAD!

3. рдХреБрдЫ рди рдХрд░реЗрдВ

рдЙрджрд╛рд╣рд░рдг:

interface State {
  foo: string;
  bar: string;
}

// The following errors out because {foo: ""} can't be assigned to Pick<State, "foo" | "bar">
// Same with {bar: "" }
setState((prevState) => {
  if (randomThing) {
    return { foo: "" };
  }
  return { bar: "" };
});

// A work around for the few places where people need this type of thing, which works
setState((prevState) => {
  if (randomThing) {
    return { foo: "" } as State
  }
  return { bar: "" } as State
});

// This is fine because the following is still an error
const a = {oops: ""} as State

4. рдЬреБрдбрд╝реЗ рд╣реБрдП рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рд▓реЙрдЬрд┐рдХ рдЬреЛрдбрд╝реЗрдВ

рдЕрднреА, рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рд░рд┐рдЯрд░реНрди рдкрде рд╣реИрдВ, рддреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╡рд┐рд╢рд╛рд▓ Pick<State, "foo" | "bar"> ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдкреАрдЫреЗ рдХреА рдУрд░ рд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрди рд╢рд╛рдмреНрджрд┐рдХ рдХреЛ рд╕рдореВрд╣реАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдирд╛ рд╣реЛрдЧрд╛, рдЬреИрд╕реЗ Pick<State, ("foo") | ("bar")> рдпрд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЗ рдореЗрдВ: Pick<State, ("foo" | "bar") | ("baz")>

рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреА рдХрдореА рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ рдЬреЛ рдореМрдЬреВрджрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИред

рдЕрдм рдЬрдм рд╣рдо {foo: number} рд╕реЗ Pick<State, ("foo") | ("bar")> рдбрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╕рдлрд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред {bar: number} рд╕рд╛рде рд╣реАред

Pick<State, ("foo") | ("bar")> рдХреЛ Partial<State> рдФрд░ {foo: number} | {bar: number} рднреА рдХрд╛рд╕реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдореЗрд░рд╛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдирд┐рд╖реНрдХрд░реНрд╖

(рез) рдФрд░ (реи) рдмрд╕ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИрдВред рдПрдХ рд▓рдЧрднрдЧ рд╕рднреА рдХреЗ рд▓рд┐рдП рдЬрдЯрд┐рд▓рддрд╛ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ, рдЪрд╛рд╣реЗ рдХреБрдЫ рднреА рд╣реЛ, рдФрд░ рджреВрд╕рд░рд╛ рд▓реЛрдЧреЛрдВ рдХреЛ рдХреЛрдб рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЧрд▓рдд рд╣реИред

(3) рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЖрдЬ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдФрд░ рдЬрдм рддрдХ рдореИрдВ рдпрд╛рдж рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдХреНрдпреЛрдВ рдореИрдВ рдЬреЛрдбрд╝рд╛ | S рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд╛рдкрд╕реА рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ setState , рдореИрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдХрд╛рд░рдг рдирд╣реАрдВ рдЬрд╛рди рд╕рдХрддрд╛ред

(рек) (рей) рдореЗрдВ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ рдФрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╣рдореЗрдВ @ahejlsberg рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реЛ рддреЛ рд╣рдо рдЗрд╕реЗ рдЬрд▓реНрдж рд╕реЗ рдЬрд▓реНрдж рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рд╕реЗ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ рддреЛ рдЖрдЬ рдХреЗ рдкреНрд░рдХрд╛рд░ рдЕрдзрд┐рдХ рд╕рд╣реА рд╣реИрдВред

"рдХреБрдЫ рднреА рди рдХрд░реЗрдВ" рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╕рдВрдХрд▓рдХ рдЙрд╕ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреИрд╕рд╛ рдЖрдк рд╡рд░реНрдгрди рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЕрдЧрд░ рдореИрдВ рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдХрд╣реЗрдВ, рдорд╛рди рдХреЛ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдмрдЬрд╛рдп 0 рд╕реЗрдЯ рдХрд░реЗрдВ:

interface State {
  foo: string;
  bar: string;
}

// The following does not error at all because the compiler picks `Pick<State, never>`
// The function overload of `setState` is not used -- the object overload is, and it
// accepts the function as it is accepting anything (`{}`).
setState((prevState) => {
  if (randomThing) {
    return { foo: 0 };
  }
  return { bar: 0 };
});

рдореБрдЭреЗ рдЕрдм рджрд┐рдЦ рдЧрдпрд╛ред рдбреНрд░реЙрдЗрдВрдЧ рдмреЛрд░реНрдб рдкрд░ рд╡рд╛рдкрд╕ред рдореИрдВ рдпрд╣ рджреЗрдЦрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдЗрд╕рдХрд╛ рдХреЛрдИ рдЪрддреБрд░ рд╕рдорд╛рдзрд╛рди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдПрдХ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рдЖ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд Partial<> рд╕рдорд╛рдзрд╛рди рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдмрдбрд╝реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдореВрд▓реНрдп рдкрд░ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд undefined рдПрдХ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп/рдХрд╖реНрдЯрдкреНрд░рдж рд╣реЛрдЧрд╛ рдпрд╛ рдирд╣реАрдВред

рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕рдХреЗ рд▓рд┐рдП рджреЛ рдЕрдзрд┐рднрд╛рд░ рд╣реИрдВ ...

setState<K extends keyof S>(f: (prevState: Readonly<S>, props: P) => Pick<S, K>, callback?: () => any): void;
setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;

рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдпрд╛ рджреЛрдиреЛрдВ рдХреЛ Partial<S> рдмрдЬрд╛рдп Pick<S, K> рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХреА рд╕рдорд╕реНрдпрд╛ рдареАрдХ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдпрд╣ рдЕрднреА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧрд┐рд░рддрд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЧрд▓рдд рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ:

```ts
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд░рд╛рдЬреНрдп {
рдмрд╛рд░: рд╕реНрдЯреНрд░рд┐рдВрдЧ;
рдлреВ: рд╕рдВрдЦреНрдпрд╛;
}

рдХреНрд▓рд╛рд╕ рдлреВ рд░рд┐рдПрдХреНрдЯ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдХреЙрдореНрдкреЛрдиреЗрдВрдЯ<{}, рд╕реНрдЯреЗрдЯ> {
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдмреНрд▓рд╛рд╣ () {
this.setState((prevState) => ({рдмрд╛рд░: 1})); // рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ: /
}
}```

рдХреНрдпрд╛ рд╣рдо рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕реЗ extends object рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдмрд╛рдзрд╛?
рд╢реБрдХреНрд░, 28 рдЬреБрд▓рд╛рдИ, 2017 рдХреЛ 0:00 рдмрдЬреЗ рдПрд░рд┐рдХ рдПрдВрдбрд░рд╕рди рд╕реВрдЪрдирд╛рдПрдВ @github.com рдиреЗ рд▓рд┐рдЦрд╛:

рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕рдХреЗ рд▓рд┐рдП рджреЛ рдЕрдзрд┐рднрд╛рд░ рд╣реИрдВ ...

рд╕реЗрдЯрд╕реНрдЯреЗрдЯ(рдПрдл: (рдкрд┐рдЫрд▓рд╛ рд░рд╛рдЬреНрдп: рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП , рд╕рд╣рд╛рд░рд╛: рдкреА) => рдЙрдард╛рдУ , рдХреЙрд▓рдмреИрдХ?: () => рдХреЛрдИ рднреА): рд╢реВрдиреНрдп; рд╕реЗрдЯрд╕реНрдЯреЗрдЯ(рд░рд╛рдЬреНрдп: рдЪреБрдиреЗрдВ , рдХреЙрд▓рдмреИрдХ?: () => рдХреЛрдИ рднреА): рд╢реВрдиреНрдп;

рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдпрд╛ рджреЛрдиреЛрдВ рдХреЛ рдкрд┐рдХ рдХреЗ рдмрдЬрд╛рдп рдЖрдВрд╢рд┐рдХ рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛рдЖрдкрдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд░рд╛рдЬреНрдп {
рдмрд╛рд░: рд╕реНрдЯреНрд░рд┐рдВрдЧ;
рдлреВ: рд╕рдВрдЦреНрдпрд╛;
}
рдХреНрд▓рд╛рд╕ рдлреВ рд░рд┐рдПрдХреНрдЯ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдХреЙрдореНрдкреЛрдиреЗрдВрдЯ<{}, рд╕реНрдЯреЗрдЯ> {
рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдмреНрд▓рд╛рд╣ () {
this.setState((prevState) => ({рдмрд╛рд░: 1})); // рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ: /
}
}```

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдиреЗ рд╕реВрддреНрд░ рдХреЛ рд▓рд┐рдЦрд╛ рд╣реИред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-318388471 ,
рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AAEdfeEJ_Ejfana14fRII1OZuS7qTuyuks5sSKX3gaJpZM4OiDrc
.

рд╣рдордиреЗ рд╡рд╣ рдХреЛрд╢рд┐рд╢ рдХреАред рдХрд╛рд░реНрдп рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВред

рдПрд░рд┐рдХ рдПрд▓ рдПрдВрдбрд░рд╕рди
рдореЗрд░реЗ рдЖрдИрдлреЛрди рд╕реЗ рднреЗрдЬрд╛ рдЧрдпрд╛

рдореИрдВ рдпрд╣рд╛рдВ рдПрдХ рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЗ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдЖрдпрд╛ рдерд╛, рдЬреЛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╕рд╛рде рд░рд╛рдЬреНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, https://github.com/tomduncalf/react-types-issue/blob/master/Test.tsx рджреЗрдЦреЗрдВ - рдпрджрд┐ рдЖрдк рдЗрд╕реЗ VS рдХреЛрдб рдореЗрдВ рдЦреЛрд▓рддреЗ рд╣реИрдВ рдФрд░ F2 рд▓рд╛рдЗрди 6 рдкрд░ something рд░рд┐рдлреИрдХреНрдЯрд░/рдирд╛рдо рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЛрд▓рддреЗ рд╣реИрдВ (https://github.com/tomduncalf/react-types-issue/blob/master/Test.tsx#L6), рдпрд╣ рдЙрд╕ рд▓рд╛рдЗрди рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛ рдФрд░ https://github.com/tomduncalf/react-types-issue/ blob/master/Test.tsx#L14 , рд▓реЗрдХрд┐рди https://github.com/tomduncalf/react-types-issue/blob/master/Test.tsx рдкрд░ setState рдХреЙрд▓ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЪреВрдХ рдЬрд╛рдПрдВрдЧреЗ #L20

рдПрдХ рд╣реА рд░рд╛рд╕реНрддрд╛ рдореИрдВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓ рдЧрдпрд╛ рд╣реИ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдореЗрд░реА рд╡рд╕реНрддреБ as IState рдЬрдм рдмреБрд▓рд╛ setState рд╣реИ, рдЬреЛ рдереЛрдбрд╝рд╛ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдФрд░ рдХрд╛рдлреА рдЖрд╕рд╛рди рднреВрд▓ рдЬрд╛рддреЗ рд╣реИрдВред

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдФрдЪрд┐рддреНрдп рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд░рд╛рдЬреНрдп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдХрд╛рдлреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рддрд░реАрдХреЗ рд╕реЗ рдЯреВрдЯрд╛ рд╣реБрдЖ рдкреНрд░рдХрд╛рд░-рд╕реБрд░рдХреНрд╖рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реЛ рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛!

рдзрдиреНрдпрд╡рд╛рдж,
рдЯреЙрдо

рд╣рд╛рдБ, рдлрд┐рд░ рд╕реЗ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ Partial рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЙрд╕ рд╕рдВрдмрдВрдз рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдмреЗрд╣рддрд░ рд░рдЦрддрд╛ рд╣реИред

рддрд░реНрдХрд╕рдВрдЧрдд рд░реВрдк рд╕реЗ, Pick рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд░рд┐рдлреИрдХреНрдЯрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдХреЛрдб рдХреА рдПрдХ рд╕реАрдорд╛/рдмрдЧ рд╣реИ рдЬрд┐рд╕реЗ рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрднреА рднреА рд╡рд┐рд╢реНрд╡рд╛рд╕ рдирд╣реАрдВ рд╣реИ рдХрд┐ Pick рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ https:// github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment -318385945 рдореЗрдВ рдЙрд▓реНрд▓реЗрдЦ рд╣реИред рдЬрдмрдХрд┐ Partial undefined рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдЬрд╣рд╛рдВ undefined рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдРрд╕рд╛ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд╡рдзрд╛рди рд░рд╣рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, Pick рдХреБрдЫ рднреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ Pick рдмрдЬрд╛рдп рдПрдХ рдЦрд╛рд▓реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛, рдЬреЛ рдХреБрдЫ рднреА рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред

https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment -318388471 рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрдкрддреНрддрд┐ рдЪреЗрдХрд░ рдореЗрдВ рдПрдХ рдмрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ? рдпрд╛ 2.3 рдпрд╛ 2.4 (рдореИрдВ рднреВрд▓ рдЧрдпрд╛) рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрдкрддреНрддрд┐ рдЪреЗрдХрд░ рдХреЛ рд╕рдЦреНрдд рдмрдирд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛?

рдПрдХ рдФрд░ рдореБрджреНрджрд╛ рдЬреЛ рдореИрдВрдиреЗ рдЕрднреА рджреЗрдЦрд╛ рд╣реИ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдХрд┐рд╕реА рдШрдЯрдХ рдореЗрдВ рдХреЛрдИ рд░рд╛рдЬреНрдп рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ (рдпрд╛рдиреА рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ React.Component ), рдпрд╛ рд░рд╛рдЬреНрдп рдХрд╛ рдкреНрд░рдХрд╛рд░ рдЦрд╛рд▓реА рд╣реИ ( {} ), рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрднреА рднреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рддреНрд░реБрдЯрд┐ рдХреЗ setState рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдореБрдЭреЗ рдЧрд▓рдд рд▓рдЧрддрд╛ рд╣реИ - рджреЗрдЦреЗрдВ https://github.com/tomduncalf/react-types-issue/blob/master/Test2.tsx

рдЖрдВрд╢рд┐рдХ рдзреНрд╡рдирд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдорд╛рдзрд╛рди рдореЗрд░реЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реИ - рдореИрдВ рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдкреИрдЪ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдзрдиреНрдпрд╡рд╛рдж,
рдЯреЙрдо

рдирдорд╕реНрддреЗ!
рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХреНрдпреЛрдВ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореИрдВ рдПрдХрд▓ рдШреЛрд╖рдгрд╛ рдореЗрдВ setState рдШреЛрд╖рдгрд╛рдУрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реВрдВ:

setState<K extends keyof S>(state: ((prevState: Readonly<S>, props: P) => Pick<S, K>) | Pick<S, K>, callback?: () => any): void;

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдкреЗрдХреНрд╖рд┐рдд рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

import * as React from 'react';

export class Comp extends React.Component<{}, { foo: boolean, bar: boolean }> {
  public render() {
    this.handleSomething();
    return null;
  }

  private handleSomething = () => {
    this.setState({ foo: '' }); // Type '""' is not assignable to type 'boolean'.
    this.setState({ foo: true }); // ok!
    this.setState({ foo: true, bar: true }); // ok!
    this.setState({}); // ok!
    this.setState({ foo: true, foo2: true }); // Object literal may only specify
    // known properties, and 'foo2' does not exist in type
    this.setState(() => ({ foo: '' })); // Property 'foo' is missing in type '() => { foo: string; }'.
    this.setState(() => ({ foo: true })); // ok!
    this.setState(() => ({ foo: true, bar: true })); // ok!
    this.setState(() => ({ foo: true, foo2: true })); // Property 'foo' is missing in type
    // '() => { foo: true; foo2: boolean; }'
    this.setState(() => ({ foo: '', foo2: true })); // Property 'foo' is missing in
    // type '() => { foo: string; foo2: boolean; }'.
    this.setState(() => ({ })); // ok!
  };
}

рдХреНрдпрд╛ рдпрд╣ рдореВрд▓ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдкрд░рд┐рд╡рд░реНрддрди рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

@mctep рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛ред

рдФрд░ рдЕрдЧрд░ рдореИрдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓реЗрддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рд╕рд╛ рдмрдврд╝рд╛рддрд╛ рд╣реВрдВ, рддреЛ рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ Partial<S> & Pick<S, K> рдмрдЬрд╛рдп Pick<S, K> рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдЖрдкрдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╛рдо рд╕реБрдЭрд╛рддрд╛ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдкреНрд░рдореБрдЦ рдирд╛рдо рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдореВрд▓реНрдп "рдХреБрдЫ | рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд" рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмреЗрд╣рддрд░ рдЬрд╛рдирддрд╛ рд╣реИ:

declare class Component<P, S> {
    setState<K extends keyof S>(state: ((prevState: Readonly<S>, props: P) => (Partial<S> & Pick<S, K>)) | (Partial<S> & Pick<S, K>), callback?: () => any): void;
}

interface State {
    foo: number;
    bar: string;
    baz?: string;
}

class Foo extends Component<{}, State> {
    constructor() {
        super();
        this.setState(() => { // error
            return {
                foo: undefined
            }
        });
        this.setState({ // error
            foo: undefined
        })
        this.setState({
            foo: 5,
            bar: "hi",
            baz: undefined
        })
    }
}

рдореИрдВ рдпрд╣ рдмрджрд▓рд╛рд╡ рдЖрдЬ рдмрд╛рдж рдореЗрдВ рдХрд░реВрдВрдЧрд╛

рд╣рд╛рд▓рд┐рдпрд╛ "рдлрд┐рдХреНрд╕" рдЕрдм рдореЗрд░реЗ рд▓рд┐рдП setState() рдХреЙрд▓рдмреИрдХ рдХреЗ рднреАрддрд░ рдХрдИ рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдЯрд╛рдЗрдкрдкреНрд░рддрд┐: 2.6.2 рд╕рднреА "рд╕рдЦреНрдд" рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде "рд╕рдЦреНрдд рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рдХрд╛рд░" рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рдХреНрд╖рдо
рдкреНрд░рдХрд╛рд░/рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛: резрем.реж.рейреж

рдХреЛрдб рдЙрджрд╛рд╣рд░рдг:

interface TestState {
    a: boolean,
    b: boolean
}

class TestComponent extends React.Component<{}, TestState> {
    private foo(): void {
        this.setState((prevState) => {
            if (prevState.a) {
                return {
                    b: true
                };
            }

            return {
                a: true
            };
        });
    }
}

рд╕рдВрдХрд▓рдХ рддреНрд░реБрдЯрд┐:

error TS2345: Argument of type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to parameter of type '((prevState: Readonly<TestState>, props: {}) => Pick<TestState, "b"> & Partial<TestState>) | (Pick<TestState, "b"> & Partial<TestState>)'.
  Type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to type 'Pick<TestState, "b"> & Partial<TestState>'.
    Type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }' is not assignable to type 'Pick<TestState, "b">'.
      Property 'b' is missing in type '(prevState: Readonly<TestState>) => { b: true; } | { a: true; }'.

522         this.setState((prevState) => {
                          ~~~~~~~~~~~~~~~~

рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк @UselessPickles рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рд╕рдорд╕реНрдпрд╛ рдХреЛ рднреА рджреЗрдЦрдирд╛ред

рдореБрдЭреЗ рдкреВрд░рд╛ рдпрдХреАрди рд╣реИ рдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд░рд╣реА рд╣реИред

рдореБрдЭреЗ рдкреВрд░рд╛ рдпрдХреАрди рд╣реИ рдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд░рд╣реА рд╣реИред рдореЗрд░реЗ рдкрд╛рд╕ setState() рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдПрдХрд╛рдзрд┐рдХ рд░рд┐рдЯрд░реНрди рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╡рд╛рд▓рд╛ рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╣реИ рдЬреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ 2+ рдорд╣реАрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореИрдВ рд╣рд░ 2 рд╕рдкреНрддрд╛рд╣ рдореЗрдВ рдПрдирдкреАрдПрдо рдирд┐рд░реНрднрд░рддрд╛ рдЙрдиреНрдирдпрди рдХреЗ рд╕рд╛рде рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдпрд╣ рд╕рдВрдХрд▓рдХ рддреНрд░реБрдЯрд┐ рдЖрдЬ рд╣реА рдореЗрд░реЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░/рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣реЛ рд░рд╣реА рд╣реИред рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдиреЗ рдЗрд╕ рдХрдВрдкрд╛рдЗрд▓рд░ рддреНрд░реБрдЯрд┐ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдирд╣реАрдВ рдХрд┐рдпрд╛ред

рдЖрдВрд╢рд┐рдХ рд╕реЗ рдкрд┐рдХ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рд╕реЗ рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд░рд╣реА рд╣реИред рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдЙрди рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рджреЗрдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк setState рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдкрд░ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рд╕рднреА рдХреБрдВрдЬреА рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реЛрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ ...

рдореИрдВ рдЙрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реВрдВ рдпрд╛ рддреЛ рдореИрдВ рд╣рдореЗрд╢рд╛ рд╕рднреА рдЪрд╛рдмрд┐рдпрд╛рдБ рд▓реМрдЯрд╛рддрд╛ рд╣реВрдВ, рдЧреИрд░-рд╕рдВрд╢реЛрдзрд┐рдд рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЛ key: prevState.key рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдпрд╛ prevState ( { ...prevState, newKey: newValue } ) рдХреЗ рд╕рд╛рде рд╕реНрдкреНрд░реЗрдб рд▓реМрдЯрд╛рдХрд░ред

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЗрд░реЗ рдХреЛрдб рдореЗрдВ рдПрдХ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд┐рдирд╛рд░реЗ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реЛ рдЬреЛ рд╕рдВрдпреЛрдЧ рд╕реЗ рдкрд╣рд▓реЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛? рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рддрд░рд╣ рдЕрдзрд┐рдХ рд╣реИ, рдЬрд╣рд╛рдВ рдпрд╣ рдпрд╛ рддреЛ рдПрдХ рдЦрд╛рд▓реА рд╡рд╕реНрддреБ рджреЗрддрд╛ рд╣реИ (рдХрд┐рд╕реА рднреА рд░рд╛рдЬреНрдп рдХреЛ рдирд╣реАрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП), рдпрд╛ рдПрдХ рдЧреИрд░-рд░рд┐рдХреНрдд рд╡рд╕реНрддреБ рджреЗрддрд╛ рд╣реИ:

interface TestState {
    a: boolean,
    b: boolean
}

class TestComponent extends React.Component<{}, TestState> {
    private foo(newValue: boolean): void {
        this.setState((prevState) => {
            if (prevState.a === newValue) {
                // do nothing if there's no change
                return { };
            }

            return {
                a: newValue,
                // force "b" to false if we're changing "a"
                b: false
            };
        });
    }
}

return null рдФрд░ return undefined рднреА рд░рд╛рдЬреНрдп рдирд╣реАрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рд╣реИрдВ (рд╡реЗ Object.assign рдФрд░ рдЗрд╕рд▓рд┐рдП this.state рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)ред

рдореБрдЭреЗ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реИ, рд╡рд░реНрддрдорд╛рди рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЙрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреА рднреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рд╢рд╛рдпрдж null рдХреЛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП, рдХрдо рд╕реЗ рдХрдо, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдРрд╕рд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЧрд▓рддреА рд╕реЗ return рдХреЛ рднреВрд▓рдиреЗ рд╕реЗ рдмрд╛рд╣рд░ рдЖ рд╕рдХрддрд╛ рд╣реИред


рд╡реИрд╕реЗ рднреА, рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЬрд╣рд╛рдВ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИ, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реНрд░реЛрдд рдХреНрд░рдо рдореЗрдВ рдХреЗрд╡рд▓ рдкрд╣рд▓рд╛ return рдХрдерди рдЪреБрдирддрд╛ рд╣реИ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╛рдзрд╛рд░рдг рдЬреЗрдирд░рд┐рдХ (рдЬреИрд╕реЗ Array рдпрд╛ Promise ) рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдорд░реНрдЬ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЙрдиреНрд╣реЗрдВ рдХрднреА рдорд░реНрдЬ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдкреНрд░рдХрд╛рд░ рдПрдХ рдореИрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреИрд╕реЗ Pick ред

рдореИрдВ рд╕рдмрд╕реЗ рд╣рд╛рд▓ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЧреИрд░-рдлрд╝рдВрдХреНрд╢рди рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдХреБрдЫ рдкреНрд░рддрд┐рдЧрдорди рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд░рддреЗ рд╕рдордп "рд░рд╛рдЬреНрдп" рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ:

рд╕реЗрдЯрд╕реНрдЯреЗрдЯ( рд░рд╛рдЬреНрдп: рдЪреБрдиреЗрдВ , рдХреЙрд▓рдмреИрдХ?: () => рдХреЛрдИ рднреА): рд╢реВрдиреНрдп;

рдкреНрд░рддрд┐:

рд░рд╛рдЬреНрдп: ((prevState: Readonly\ , рд╕рд╣рд╛рд░рд╛: P) => (рдЪреБрдиреЗрдВ рдФрд░ рдЖрдВрд╢рд┐рдХ\ )) |

https://github.com/DefinitelyTyped/DefinitelyTyped/commit/62c2219a6ed6dc34ea969b8c2c87a41d31002660#diff -96b72df8b13a8a590e4f160cbc51f40c

& Partial<S> рдХрд╛ рдЬреЛрдбрд╝ рдЙрди рдЪреАрдЬреЛрдВ рдХреЛ рддреЛрдбрд╝рддрд╛ рд╣реБрдЖ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рдХрд╛рдо рдХрд░рддреА рдереАрдВред

рдпрд╣рд╛рдБ рдПрдХ рдиреНрдпреВрдирддрдо рд░реЗрдкреЛ рд╣реИ:

export abstract class ComponentBaseClass<P, S = {}> extends React.Component<P, S & { baseProp: string }>
{
    foo()
    {
        this.setState( { baseProp: 'foobar' } );
    }
}

рдпрд╣ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ:

(рекреиреп,резрео): рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ '{рдмреЗрд╕рдкреНрд░реЙрдк: "рдлреЛрдмрд╛рд░"; }' рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ '((prevState: Readonly Type' {baseProp: "foobar"; }' рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ 'Pick & Partial Type' {baseProp: "foobar"; }' рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ 'рдЖрдВрд╢рд┐рдХ' рдЯрд╛рдЗрдк рдХрд░реЗрдВ

рд░рд╛рдЬреНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ S &{ baseProp: string } рд╕реЗ рдмрджрд▓рдХрд░ рдХреЗрд╡рд▓ { baseProp: string } рд╕реЗ рднреА рддреНрд░реБрдЯрд┐ рджреВрд░ рд╣реЛ рдЬрд╛рдПрдЧреА (рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡рд░реНрдЧреЛрдВ рдХреЛ рддреЛрдбрд╝ рджреЗрдЧрд╛ рдЬреЛ S рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ)ред

рдпрд╣ рддреЛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИред рдореБрдЭреЗ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд╛рдкрд╕ рд░реЛрд▓ рдХрд░рдиреЗ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдЪреБрдирдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛ рд░рд╣реА рд╣реИ

рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдЖрдк рдЬреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ TS рдореЗрдВ рдПрдХ рдмрдЧ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ:

рдЯрд╛рдЗрдк рдХрд░реЗрдВ '{рдмреЗрд╕рдкреНрд░реЙрдк: "рдлреЛрдмрд╛рд░"; }' 'рдЖрдВрд╢рд┐рдХ' рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ

рдареАрдХ рд╣реИред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ TS рдХреЛ рдкрддрд╛ рди рдЪрд▓реЗ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ S рдФрд░ рдмреЗрд╕рдкреНрд░реЙрдк рдХреЗ рдмреАрдЪ рдХреЛрдИ рд╕рдВрдмрдВрдз рдирд╣реАрдВ рд╣реИред

рдХреЛрдИ рдПрдХ рдПрд╕ рдкрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдк { рдмреЗрд╕рдкреНрд░реЙрдк: рдирдВрдмрд░ } рд╣реИ, рдЬрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдпрд╣ рд╕рд╣реА рд╣реИ рдХрд┐ рдЖрдк рдмреЗрд╕рдкреНрд░реЙрдк рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЕрд╕рд╛рдЗрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

рд╢рд╛рдпрдж рдЕрдЧрд░ рдПрд╕ рдиреЗ рдмреЗрд╕рдкреНрд░реЙрдк рд╕рдВрд╕реНрдХрд░рдг рдмрдврд╝рд╛рдпрд╛?

рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдРрд╕рд╛ рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдереА:

interface BaseState_t
{
    baseProp: string
}

export abstract class ComponentBaseClass<P, S extends BaseState_t> extends React.Component<P, S >
{
    foo()
    {
        this.state.baseProp;
        this.setState( { baseProp: 'foobar' } );
    }
}

рдЬрдмрдХрд┐ рдкрд╣реБрдВрдЪ рдареАрдХ рд╣реИ, рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЙрд▓ рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рд╣реИ:

рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ '{рдмреЗрд╕рдкреНрд░реЙрдк: "рдлреЛрдмрд╛рд░"; }' рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ '((prevState: Readonly\ , props \ ) |
}' 'рдЪреБрдиреЗрдВ рдФрд░ рдЖрдВрд╢рд┐рдХ ' рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ рдЯрд╛рдЗрдк рдХрд░реЗрдВ '{рдмреЗрд╕рдкреНрд░реЙрдк: "рдлреЛрдмрд╛рд░";

рдпрд╣ рд╢рд╛рдпрдж рдЗрд╕реЗ рд╕рдВрд░рдЪрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ - рдЖрдЦрд┐рд░рдХрд╛рд░, рдХреБрдЫ рдмрд╛рд▓ рд╡рд░реНрдЧ рд░рд╛рдЬреНрдп рдЪрд░ рдШреЛрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдкрд░ рдЪрд░ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рддреЗ рд╣реИрдВред рддреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╢рд┐рдХрд╛рдпрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рдХрд┐ рд╡рд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛрдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдпрд╣ рдЕрдЬреАрдм рд╣реИ рдХрд┐ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрди рдкреНрд░реЙрдкреНрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред

рд╣рдореНрдоред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдм рдЯреАрдПрд╕ рдореЗрдВ рдПрдХ рдмрдЧ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИред

рдореИрдВ рдЖрдЬ рдЗрд╕рдХреЗ рд╕рд╛рде рдЦреЗрд▓реВрдВрдЧрд╛ рдФрд░ рд╕рдВрднрд╡рдд: рдФрд░ рдЖрдВрд╢рд┐рдХ рдирд┐рдХрд╛рд▓реВрдВрдЧрд╛ред

рдореИрдВ рдЗрд╕реЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЬреЛрдбрд╝реВрдВрдЧрд╛ рдФрд░ рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдХреЛ рдЦреБрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рд╡рд┐рдЪрд╛рд░ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛

рдирдорд╕реНрддреЗ,
рд╡рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИ...

export interface ISomeComponent {
    field1: string;
    field2: string;
}

interface SomeComponentState {
    field: string;
}

export class SomeComponent<
    TProps extends ISomeComponent = ISomeComponent,
    TState extends SomeComponentState = SomeComponentState> extends React.Component<TProps, TState>{

    doSomething() {
        this.setState({ field: 'test' });
    }

    render() {
        return (
            <div onClick={this.doSomething.bind(this)}>
                {this.state.field}
            </div>
        );
    }
}

рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдореЗрдВ рддреНрд░реБрдЯрд┐:
TS2345 (TS) Argument of type '{ field: "test"; }' is not assignable to parameter of type '((prevState: Readonly<TState>, props: TProps) => Pick<TState, "field"> & Partial<TState>) | (Pick...'. Type '{ field: "test"; }' is not assignable to type 'Pick<TState, "field"> & Partial<TState>'. Type '{ field: "test"; }' is not assignable to type 'Partial<TState>'.

рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рд╣реА рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рд▓рдЧреАред рд╕рдВрд╕реНрдХрд░рдг 16.0.10 рдореЗрдВ рдЗрд╕рдиреЗ рдареАрдХ рдХрд╛рдо рдХрд┐рдпрд╛ред

рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдХрдИ рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдВрдж рдХрд░ рджрд┐рдпрд╛ рд╣реИ:

https://github.com/Microsoft/TypeScript/issues/19388

рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рд╕рд╛рд░ рджрд┐рдпрд╛ рд╣реИ: https://gist.github.com/afarnsworth-valve/93d1096d1410b0f2efb2c94f86de9c84

рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрднреА рднреА рдЕрдЬреАрдм рд▓рдЧрддрд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдк рдмрд┐рдирд╛ рдХрд╛рд╕реНрдЯ рдХреЗ рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рдЙрд╕реА рдХреЙрд▓ рдХреЛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐

рдЖрдк рд▓реЛрдЧ рдирд╣реАрдВ рднреВрд▓реЗ рд╣реИрдВред рдЬрд▓реНрдж рд╣реА рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗ

рд╕рдВрджрд░реНрднрд┐рдд рдкреАрдЖрд░ рдХреЛ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВрдиреЗ рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдг рднреА рдЬреЛрдбрд╝реЗ рдЬреЛ рдЗрд╕ рдмрдврд╝рдд рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреЛрдбрд╝рдиреЗ рд╕реЗ рдмрдЪрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

@ericanderson рддреНрд╡рд░рд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж :)

рдХреНрдпрд╛ рдирдП рдлрд╝рд┐рдХреНрд╕реЗрд╕ рдХреА рдХреЛрдИ рд╕реАрдорд╛рдПрдБ/рдирдХрд╛рд░рд╛рддреНрдордХ рдкрд╣рд▓реВ рд╣реИрдВ?

рдХреЛрдИ рднреА рдирд╣реАрдВ рдЬреЛ рдореБрдЭреЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкрддрд╛ рд╣реИред рдореИрдВ рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рд░рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдмреЗрд╣рддрд░, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХреБрдЫ рдХрд┐рдирд╛рд░реЗ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ)ред

рд╡рд┐рд╕реНрддреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, & Partial<S> рд╕рдорд╛рдзрд╛рди рд╕рдВрднрд╛рд╡рд┐рдд рдкреИрд░рд╛ рдХреЛ рдкреНрд░рдХрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдХреЛ рдЪрдХрдорд╛ рджреЗрдирд╛ рдерд╛, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдпрд╣ рдмрддрд╛рддреЗ рд╣реБрдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХрд┐ рд╡реЗ X | undefined ред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛрдЧрд╛ рд▓реЗрдХрд┐рди рдпрд╣ рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛ред | S рдХрд░рдирд╛ рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдХреЛ рдареАрдХ рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рд╕рднреА рд╕рд╣реА рдкреИрд░рд╛ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗ рдФрд░ рдЕрдм рдпрд╣ рдЭреВрдард╛ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рджрд┐рдЦрд╛рддрд╛ рд╣реИред

рдореИрдВ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рджреЗрдЦ рдХреЛрд╢рд┐рд╢ рдХреА null рд╕реЗ рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд╛рдкрд╕реА рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ setState рдХреЙрд▓рдмреИрдХ (рдЖрдк рд░рд╛рдЬреНрдп рдХреЗ рд▓рд┐рдП рддреБрдо рдирд╣реАрдВ рд▓реМрдЯ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпрд╛, рдХрд┐рд╕реА рднреА рд░рд╛рдЬреНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ return; рдорд╛рдиреНрдп рднреА рд╣реИ), рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЯрд╛рдЗрдк рдЕрдиреБрдорд╛рди рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЫреЛрдбрд╝ рджреЗрдВ рдФрд░ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ never рдЪреБрдиреЗрдВ

рдЕрднреА рдХреЗ рд▓рд┐рдП, рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдЬрд╣рд╛рдВ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрджреНрдпрддрди рд╕реНрдерд┐рддрд┐ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдореИрдВ return null! рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдЗрд╕ рд░рд┐рдЯрд░реНрди рдХрд╛ never рдкреНрд░рдХрд╛рд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдиреБрдорд╛рди рдХреЗ рд▓рд┐рдП рд░рд┐рдЯрд░реНрди рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред

рд╣рд╛рдп рджреЛрд╕реНрддреЛрдВ...

рдЖрдЦрд┐рд░реА рдХрдорд┐рдЯрдореЗрдВрдЯ рдиреЗ рдореЗрд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░ рджрд┐рдпрд╛ред
рддреБрд░рдВрдд рдкреНрд░рддрд┐рд╕рд╛рдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж :)

рдХрд┐рд╕ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдлрд┐рдХреНрд╕ рд╣реИ? рдХреНрдпрд╛ рдпрд╣ npm рдкрд░ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реБрдЖ рд╣реИ? рдореИрдВ рдЙрд╕ рдорд╛рдорд▓реЗ рдХреЛ рдорд╛рд░ рд░рд╣рд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХрд╛ рдХреЙрд▓рдмреИрдХ рд╕рдВрд╕реНрдХрд░рдг рдореБрдЭреЗ рдмрддрд╛ рд░рд╣рд╛ рд╣реИ рдХрд┐ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдореЗрдВ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдореЗрд▓ рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕реЗ @UselessPickles рдорд┐рд▓рд╛ред

рдирд╡реАрдирддрдо @types/react . рдкрд░ рдЕрдЪреНрдЫрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП

рдореИрдВрдиреЗ рдЗрд╕реЗ резрел рдФрд░ резрем рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд▓рд┐рдП рддрдп рдХрд┐рдпрд╛

import produce from 'immer';

interface IComponentState
{
    numberList: number[];
}

export class HomeComponent extends React.Component<ComponentProps, IComponentState>

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреБрд░рд╛рдиреА рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ ..

// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState<K extends keyof S>(
    state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> | S)) | (Pick<S, K> | S),
    callback?: () => void
): void;

.. рдпрд╣ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ:

screen shot 2018-05-18 at 2 36 44 pm

рдореИрдВрдиреЗ рдЗрд╕ рд╕реБрдЭрд╛рд╡ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА:

setState<K extends keyof S>(
    state:
        ((prevState: Readonly<S>, props: P) => (Partial<S> & Pick<S, K>))
        | (Partial<S> & Pick<S, K>),
    callback?: () => any
): void;

рдЗрдВрдЯреЗрд▓рд┐рд╕реЗрдВрд╕ рдЕрдм рд░рд┐рдПрдХреНрдЯ рдХреА рд╕реНрдерд┐рддрд┐ рд╕реЗ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕рдВрд╡реЗрджреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдЕрдм possibly undefined рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред

screen shot 2018-05-18 at 2 37 32 pm

рдЕрд╢рдХреНрдд рдЕрднрд┐рдХрдерди рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рднрд▓реЗ рд╣реА рд╕рдВрдЦреНрдпрд╛рд╕реВрдЪреА рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рд╣реИ рдФрд░ рди рд╣реА рдЕрд╢рдХреНрдд рд╣реИ:

screen shot 2018-05-18 at 2 38 51 pm

рдЬрдм рддрдХ рдЯрд╛рдЗрдк рд╕реЗрдВрд╕рд┐рдВрдЧ рдореЗрдВ рд╕реБрдзрд╛рд░ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛, рддрдм рддрдХ рдореИрдВ рдкреБрд░рд╛рдиреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рдмрдирд╛ рд░рд╣реВрдВрдЧрд╛ред рдЗрд╕ рдмреАрдЪ, рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрдорд░ рдЙрддреНрдкрд╛рджрди рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрддрд╛рдКрдВрдЧрд╛ред produce<IComponentState> list! рддреБрд▓рдирд╛ рдореЗрдВ рддрд░реНрдХ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред

screen shot 2018-05-18 at 2 51 43 pm

рдЖрдкрдХреА рдкрд╣рд▓реА рддреНрд░реБрдЯрд┐ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдпрд╣ рддрдм рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдПрдХ рдЪрд░ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд┐рдпрд╛ рд╣реИ (рдЧреИрд░-рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ):

https://github.com/mweststrate/immer

onBirthDayClick2 = () => {
    this.setState(
        produce(draft => {
            draft.user.age += 1
            // no need to return draft
        })
    )
}

рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЙрд╕ рдХреЛрдб рдХреЛ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рд╡рд╛рд▓реА рдПрдХрдорд╛рддреНрд░ рдЪреАрдЬ рдпрд╣ рд╣реИ рдХрд┐ рд░рд┐рдПрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдЕрдиреБрдорд╛рдирд┐рдд рдкреНрд░рдХрд╛рд░ рд╣реИред рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ numberList does not exist on type Pick<IComponentState, never> рддреНрд░реБрдЯрд┐ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреА рд╣реИред рдЙрддреНрдкрд╛рджрди рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░, рдпрд╛рдиреА produce<IComponentState> рдкрд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд╛рд╕ рдХрд░рдХреЗ рд╕рдВрдХрд▓рд┐рдд рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред

рдореИрдВрдиреЗ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рднреА рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд░рд┐рдПрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рдкреНрд░рдХрд╛рд░ (рдПрдХ рдЪрд┐рдХ-рдПрдВрдб-рдПрдЧ рд╕рдорд╕реНрдпрд╛) рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рд░рд╛рдЬреНрдп рдХреЗ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд┐рдПрдХреНрдЯ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд░рд╛рд╕реНрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП рдбреНрд░рд╛рдлреНрдЯ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯреЗрд▓рд┐рдЬреЗрдВрд╕ рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╣реАрдВ рд╣реЛ рд░рд╣рд╛ рд╣реИ:

screen shot 2018-05-18 at 10 38 04 pm

рдпрд╛ рд╢рд╛рдпрдж рдореБрдЭреЗ рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реЗ рдЧрд▓рдд рдЙрдореНрдореАрдж рд╣реИ :) рдХрдВрдкрд╛рдЗрд▓рд░ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдбреНрд░рд╛рдлреНрдЯ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛрдб рдХреЛ рдЕрдВрджрд░ рд╕реЗ рдмрд╛рд╣рд░ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕реБрдЭрд╛рдИ рдЧрдИ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдиреЗ рдХрд┐рд╕реА рддрд░рд╣ рдореБрдЭреЗ рдпрд╣ рд╕реЛрдЪрдиреЗ рдкрд░ рдордЬрдмреВрд░ рдХрд░ рджрд┐рдпрд╛ рдХрд┐ рд╕рдВрдХрд▓рдХ рдмрд╛рд╣рд░ рд╕реЗ рдХреЛрдб рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдХрд┐ рд╡рд╣ рдмрд╛рд╣рд░реА рдХреЛрдб ( setState ) рд╕реЗ рдЖрдВрддрд░рд┐рдХ рдХреЛрдб ( produce ) рдореЗрдВ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреНрд░рдХрд╛рд░ рдЪреБрди рд╕рдХрддрд╛ рд╣реИред

setState<K extends keyof S>(
    state:
        ((prevState: Readonly<S>, props: P) => (Partial<S> & Pick<S, K>))
        | (Partial<S> & Pick<S, K>),
    callback?: () => any
): void;

рдЙрдкрд░реЛрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде, рд╕рдВрдХрд▓рдХ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдорд╕реМрджреЗ рдореЗрдВ numberList рд╕рдВрдкрддреНрддрд┐ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЗрд╕реЗ possibly undefined рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ:

image

рдЖрдЧреЗ рдХреА рдЫреЗрдбрд╝рдЫрд╛рдбрд╝ рдкрд░, рдореИрдВрдиреЗ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреА рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ S рдЬреЛрдбрд╝рдХрд░ рд░рд╛рдЬреНрдп рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЙрддреНрдкрд╛рджрди рдХреЗ рдорд╕реМрджреЗ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рдпрд╛:

setState<K extends keyof S>(
    state:
        ((prevState: Readonly<S>, props: P) => (Partial<S> & Pick<S, K> & S))
        | (Partial<S> & Pick<S, K>),
    callback?: () => any
): void;

рдХреЛрдб рдЕрдм рд╕рдВрдХрд▓рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИ :)

screen shot 2018-05-18 at 11 21 03 pm

рдЖрдкрдХреА рддреНрд░реБрдЯрд┐ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИ, рдЖрдкрдХреА рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрд╛рджрди рдХреЗ рдЕрдВрджрд░ рд╣реИред рдЙрддреНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдЖрдкрдХреА рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреНрдпрд╛ рд╣реИ?

рдЙрдкрд░реЛрдХреНрдд рдореЗрд░реЗ рдкреАрдЖрд░ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХреА рдЧрдИ рдЯреЗрд╕реНрдЯ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рддреНрд░реБрдЯрд┐ рд╣реИ, рдореИрдВрдиреЗ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЕрднреА рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдпрд╣рд╛рдБ рдЗрдорд░/рдЙрддреНрдкрд╛рджрди рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИред

/**
 * Immer takes a state, and runs a function against it.
 * That function can freely mutate the state, as it will create copies-on-write.
 * This means that the original state will stay unchanged, and once the function finishes, the modified state is returned.
 *
 * If the first argument is a function, this is interpreted as the recipe, and will create a curried function that will execute the recipe
 * any time it is called with the current state.
 *
 * <strong i="7">@param</strong> currentState - the state to start with
 * <strong i="8">@param</strong> recipe - function that receives a proxy of the current state as first argument and which can be freely modified
 * <strong i="9">@param</strong> initialState - if a curried function is created and this argument was given, it will be used as fallback if the curried function is called with a state of undefined
 * <strong i="10">@returns</strong> The next state: a new state, or the current state if nothing was modified
 */
export default function<S = any>(
    currentState: S,
    recipe: (this: S, draftState: S) => void | S
): S

// curried invocations with default initial state
// 0 additional arguments
export default function<S = any>(
    recipe: (this: S, draftState: S) => void | S,
    initialState: S
): (currentState: S | undefined) => S
// 1 additional argument of type A
export default function<S = any, A = any>(
    recipe: (this: S, draftState: S, a: A) => void | S,
    initialState: S
): (currentState: S | undefined, a: A) => S
// 2 additional arguments of types A and B
export default function<S = any, A = any, B = any>(
    recipe: (this: S, draftState: S, a: A, b: B) => void | S,
    initialState: S
): (currentState: S | undefined, a: A, b: B) => S
// 3 additional arguments of types A, B and C
export default function<S = any, A = any, B = any, C = any>(
    recipe: (this: S, draftState: S, a: A, b: B, c: C) => void | S,
    initialState: S
): (currentState: S | undefined, a: A, b: B, c: C) => S
// any number of additional arguments, but with loss of type safety
// this may be alleviated if "variadic kinds" makes it into Typescript:
// https://github.com/Microsoft/TypeScript/issues/5453
export default function<S = any>(
    recipe: (this: S, draftState: S, ...extraArgs: any[]) => void | S,
    initialState: S
): (currentState: S | undefined, ...extraArgs: any[]) => S

// curried invocations without default initial state
// 0 additional arguments
export default function<S = any>(
    recipe: (this: S, draftState: S) => void | S
): (currentState: S) => S
// 1 additional argument of type A
export default function<S = any, A = any>(
    recipe: (this: S, draftState: S, a: A) => void | S
): (currentState: S, a: A) => S
// 2 additional arguments of types A and B
export default function<S = any, A = any, B = any>(
    recipe: (this: S, draftState: S, a: A, b: B) => void | S
): (currentState: S, a: A, b: B) => S
// 3 additional arguments of types A, B and C
export default function<S = any, A = any, B = any, C = any>(
    recipe: (this: S, draftState: S, a: A, b: B, c: C) => void | S
): (currentState: S, a: A, b: B, c: C) => S
// any number of additional arguments, but with loss of type safety
// this may be alleviated if "variadic kinds" makes it into Typescript:
// https://github.com/Microsoft/TypeScript/issues/5453
export default function<S = any>(
    recipe: (this: S, draftState: S, ...extraArgs: any[]) => void | S
): (currentState: S, ...extraArgs: any[]) => S
/**
 * Automatically freezes any state trees generated by immer.
 * This protects against accidental modifications of the state tree outside of an immer function.
 * This comes with a performance impact, so it is recommended to disable this option in production.
 * It is by default enabled.
 */
export function setAutoFreeze(autoFreeze: boolean): void

/**
 * Manually override whether proxies should be used.
 * By default done by using feature detection
 */
export function setUseProxies(useProxies: boolean): void

@ericanderson рдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рдХреНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ Pick рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ Partial ? рдпрд╣ рдореБрдЭреЗ рдШрдВрдЯреЛрдВ рджреБрдГрдЦ рджреЗ рд░рд╣рд╛ рд╣реИ (рд╕рд╛рджреЗ setState(obj) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдХреЙрд▓рдмреИрдХ рд╕рдВрд╕реНрдХрд░рдг рдирд╣реАрдВ), рдФрд░ рдЕрднреА рдХреЗ рд▓рд┐рдП рдореИрдВ рдПрдХ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рд░реВрдк рдореЗрдВ this.setState(newState as State) рд╕рд╛рде рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕реЗ рдХреНрдпреЛрдВ рдмрджрд▓рд╛ рдЧрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдХреБрдЫ рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реЛрдЧрд╛ред

рд╣реИрд▓реЛ @ericanderson ,

рдореБрдЭреЗ рдирд╡реАрдирддрдо рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдХреБрдЫ рд╕рдорд╕реНрдпрд╛ рд╣реИред

рдореЗрд░рд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

interface AppState {
  valueA: string;
  valueB: string;
  // ... something else
} 
export default class App extends React.Component <{}, AppState> {
  onValueAChange (e:React.ChangeEvent<HTMLInputElement>) {
    const newState: Partial<AppState> = {valueA: e.target.value}
    if (this.shouldUpdateValueB()) {
      newState.valueB = e.target.value;
    }
    this.setState(newState); // <-- this leads to a compiling error
  }
  // ... other methods
}

рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

Argument of type 'Partial<AppState>' is not assignable to parameter of type 'AppState | ((prevState: Readonly<AppState>, props: {}) => AppState | Pick<AppState, "valueA" | "v...'.
  Type 'Partial<AppState>' is not assignable to type 'Pick<AppState, "valueA" | "valueB" | "somethingElse">'.
    Types of property 'valueA' are incompatible.
      Type 'string | undefined' is not assignable to type 'string'.
        Type 'undefined' is not assignable to type 'string'.

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Partial<AppState> setState рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИред рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдореИрдВ рдЗрд╕реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рджрд╛рд╡реЗ рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬреИрд╕реЗ

this.setState(newState as Pick<AppState, 'valueA' | 'valueB'>)

рд▓реЗрдХрд┐рди рдпрд╣ рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐:
рез) рдпрд╣ рд╡рд╛рдХреНрдп-рд╡рд┐рдиреНрдпрд╛рд╕ рдмрд╣реБрдд рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╣реИ
2) рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдк рдЕрднрд┐рдХрдерди рдореЗрд░реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, newState as Pick<AppState, 'somethingElse'> рднреА рдЪреЗрдХ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдореЗрд░реЗ рдбреЗрдЯрд╛ рдореЗрдВ рдлрд┐рдЯ рдирд╣реАрдВ рдмреИрдарддрд╛ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдЖрдВрд╢рд┐рдХрдкрд┐рдХ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рддрд░рд╣ рд╕рдВрдЧрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЖрдВрд╢рд┐рдХ рдХреЗ рдмрд╛рдж рд╕реЗрдмрд╕ рдЯреА рд╕реЗ рдЪрд╛рдмрд┐рдпреЛрдВ рдХреА рдЕрдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдЪреБрдирддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореЗрд░реА рд╕рдордЭ рд╕рдЯреАрдХ рд╣реИред рд╡реИрд╕реЗ рднреА рдореЗрд░реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдЖрджрд░реНрд╢ рдЙрдкрдпреЛрдЧ рдпрд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдореИрдВ рдЖрдВрд╢рд┐рдХ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдЪрд░ рдХреЛ рдкрд╛рд╕ рдХрд░ рд╕рдХреВрдВрд╕реАрдзреЗ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдореЗрдВред

рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдореЗрд░реЗ рд╕реБрдЭрд╛рд╡ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдпрджрд┐ рдХреЛрдИ рд╣реИ рддреЛ рдореЗрд░реА рдЧрд▓рддрдлрд╣рдореА рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рд╢реБрдХреНрд░рд┐рдпрд╛!

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдмрд╕реЗ рдкреБрд░рд╛рдирд╛ рдмрджрд▓рд╛рд╡ рд╣реИред рддреЛ рдЬрдм рддрдХ рдХрд┐рд╕реА рдФрд░ рдиреЗ рдЗрд╕реЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, рдЖрдк рд╢рд╛рдпрдж рдЧрд▓рдд рдкреЗрдбрд╝ рдХреЛ рднреМрдВрдХ рд░рд╣реЗ рд╣реИрдВред

рдиреЗ рдХрд╣рд╛ рдХрд┐ред рдЖрдВрд╢рд┐рдХ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдХрд╛рд╕реНрдЯ рдП: рдЖрдВрд╢рд┐рдХ <{foo: рд╕реНрдЯреНрд░рд┐рдВрдЧ}> = {рдлреВ: рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд}

a рдорд╛рдиреНрдп рд╣реИ рд▓реЗрдХрд┐рди рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдореЗрдВ рдЙрд╕ рдЕрджреНрдпрддрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдЖрдкрдХреЗ рд░рд╛рдЬреНрдп рдХреЛ foo рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж рд░рдЦрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдЖрдкрдиреЗ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдЕрд╕рдВрднрд╡ рд╣реИред

рдЗрд╕рд▓рд┐рдП рдПрдХ рдЖрдВрд╢рд┐рдХ рдПрдХ рдкрд┐рдХ рдХреЗ рд▓рд┐рдП рдЖрдмрдВрдЯрд┐рдд рдирд╣реАрдВ рд╣реИред рдФрд░ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдкреНрд░рдХрд╛рд░ рдЭреВрда рдирд╣реАрдВ рдмреЛрд▓рддреЗ рд╣реИрдВ, рдкрд┐рдХ рд╕рд╣реА рдЙрддреНрддрд░ рд╣реИ

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗ рд░рд╣рд╛ рд╣реИ:

setState((prevState) => {
  if (prevState.xyz) {
    return { foo: "" };
  }
  return { bar: "" };
});

рдЕрддрд┐ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реИред

@ рдХреЛрд╡реЗрдиреНрд╕реНрдХреА рдХрд╛

рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдореИрдВ рдХрд╣реВрдВрдЧрд╛) рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рдкреИрдЯрд░реНрди?

рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рд╡рд╣ рд╣реИ рдЯрд╛рдЗрдкрд╕реЗрдлреНрдЯреА рдХреЛ рд╣рдЯрд╛рдирд╛

рдХреНрдпрд╛ рдХреЛрдИ Pick<S, K> | S | null рдХреЗ рддрд░реНрдХ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

        setState<K extends keyof S>(
            state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
            callback?: () => void
        ): void;

рдЯреАрдмреАрдПрдЪ рдореИрдВ рдЕрдм рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдХреНрдпреЛрдВ рдКрдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдЖрдВрд╢рд┐рдХ рд░рд╛рдЬреНрдп рдЕрдкрдбреЗрдЯ рдХреЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ K рдХреЛ keyof S рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП Pick<S, K> рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ S рдлрд┐рд░ рд╕реЗ рдмрдирд╛рддрд╛ рд╣реИ?

Partial<S> | null рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

        setState(
            state: ((prevState: Readonly<S>, props: Readonly<P>) => (Partial<S> | null)) | (Partial<S> | null),
            callback?: () => void
        ): void;

рдХреНрдпрд╛ рдХреЛрдИ рд╕рдордЭрд╛ рд╕рдХрддрд╛ рд╣реИ...

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХреБрдЫ рдЙрддреНрддрд░реЛрдВ рдХреЛ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

setState((prevState) => {
  if (prevState.xyz) {
    return { foo: "" };
  }
  return { bar: "" };
});

рдЕрддрд┐ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реИред

@ рдХреЛрд╡реЗрдиреНрд╕реНрдХреА рдХрд╛

рдореИрдВрдиреЗ рдЕрднреА рдЗрд╕ рд╕рдЯреАрдХ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдорд╛рд░рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдзрд╛рдЧреЗ рдореЗрдВ рдХреЛрд╡реЗрдиреНрд╕реНрдХреА рдХрд╛ рдХреЛрдИ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ (рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдиреЗ рдЕрдкрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рдмрджрд▓ рджрд┐рдпрд╛ рд╣реЛ?) рдХреНрдпрд╛ рдХреЛрдИ рдореБрдЭреЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрдиреБрд╢рдВрд╕рд┐рдд рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

@ timrobinson33 рдпрд╣ рдЯрд┐рдкреНрдкрдгреА рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддреА рд╣реИ https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment -351884578

рдФрд░ рдпрд╣ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдм рдФрд░ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ

@ timrobinson33 рдпрд╣ рдЯрд┐рдкреНрдкрдгреА рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб #резреорейремрел (рдЯрд┐рдкреНрдкрдгреА) рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рддреА рд╣реИ

рдЙрд╕рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред рдЕрдВрдд рдореЗрдВ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдореЗрд░рд╛ рдХреЛрдб рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдХрдИ рдЫреЛрдЯреЗ рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЙрд▓ рдЙрдирдХреЗ рдмрд╛рд╣рд░ If рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рд╕рд╛рде рдереЗ, рднрд▓реЗ рд╣реА рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХреБрдЫ рдкрде рд╕реЗрдЯрд╕реНрдЯреЗрдЯ рдХреЛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдорд╛рди рд╣реИ рдХрд┐ рд╣рдо рд╣реБрдХ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рд░рд╛рдЬреНрдп рдХреЛ рдХрдИ рдЫреЛрдЯреА рдЪреАрдЬреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕
bleepcoder.com рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рджреБрдирд┐рдпрд╛ рднрд░ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдкреНрд░рд╛рдкреНрдд GitHub рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣рдо GitHub, Inc. рдпрд╛ рдХрд┐рд╕реА рднреА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрдмрджреНрдз рдирд╣реАрдВ рд╣реИрдВ рдЬреЛ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП GitHub рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд┐рд╕реА рднреА рд╡реАрдбрд┐рдпреЛ рдпрд╛ рдЪрд┐рддреНрд░ рдХреА рдореЗрдЬрдмрд╛рдиреА рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд╕рднреА рдЕрдзрд┐рдХрд╛рд░ рдЙрдирдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рдорд╛рд▓рд┐рдХреЛрдВ рдХреЗ рд╣реИрдВред
рдЗрд╕ рдкреЗрдЬ рдХреЗ рд▓рд┐рдП рд╕реЛрд░реНрд╕: рд╕реНрд░реЛрдд

рд▓реЛрдХрдкреНрд░рд┐рдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдПрдВ
рд▓реЛрдХрдкреНрд░рд┐рдп рдЧрд┐рдЯрд╣рдм рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ
рдЕрдзрд┐рдХ рдЧрд┐рдЯрд╣рдм рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ

┬й 2024 bleepcoder.com - Contact
Made with in the Dominican Republic.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.