Definitelytyped: [@ types / response] Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ состояниС с ΠΈΠΌΠ΅Π½Π΅ΠΌ динамичСского ΠΊΠ»ΡŽΡ‡Π°, бСзопасноС для Ρ‚ΠΈΠΏΠΎΠ²

Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ Π½Π° 18 июн. 2018  Β·  12ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ  Β·  Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: DefinitelyTyped/DefinitelyTyped

Если Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, ΠΊΠ°ΠΊ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, сдСлайтС запрос Π½Π° пСрСнос.

  • [x] Π― ΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°ΠΊΠ΅Ρ‚ @types/react , ΠΈ Ρƒ мСня Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.
  • [x] Π― ΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ послСднюю ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ tsc. https://www.npmjs.com/package/typescript
  • [x] Π£ мСня вопрос, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для StackOverflow . (ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π°, Π·Π°Π΄Π°Π²Π°ΠΉΡ‚Π΅ Ρ‚Π°ΠΌ Π»ΡŽΠ±Ρ‹Π΅ умСстныС вопросы).
  • [x] [Π£ΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΠ΅] (https://github.com/blog/821-mention-somebody-they-re-notified) Π°Π²Ρ‚ΠΎΡ€ΠΎΠ² (см. Definitions by: Π² index.d.ts ), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ.

    • Авторы: @johnnyreilly , @bbenezech , @pzavolinsky , @digiguru , @ericanderson , @morcerf , @tkrotoff , @DovydasNavickas , @onigoetz , @ theruther4d , @guilhermehubner , @ferdaber , @jrakotoharisoa

Если Π²Ρ‹ Π½Π΅ ΡƒΠΊΠ°ΠΆΠ΅Ρ‚Π΅ Π°Π²Ρ‚ΠΎΡ€ΠΎΠ², вопрос Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½.

Π― Π½Π΅ ΠΌΠΎΠ³Ρƒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ setState с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, созданным ΠΈΠ· ΠΈΠΌΠ΅Π½ΠΈ вычисляСмого свойства с Ρ‚ΠΈΠΏΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ:

type State = {
  username: string,
  password: string
};

type StateKeys = keyof State;

class A extends React.Component<{}, State> {
  dynSetState(key: StateKeys, value: string) {
    this.setState({
      [key]: value // Error here. Pretty sure key is in StateKeys
    });
  }
}

МнС извСстно ΠΎ # 18365 ΠΈ ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡƒΡ‚ΠΈ Π² https://github.com/DefinitiTyped/DefinitiTyped/issues/18365#issuecomment -351868649. Однако ΠΏΡ€ΠΈ использовании ΠΎΠ±Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡƒΡ‚ΠΈ Typescript Π½Π΅ Π²Ρ‹Π΄Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½:

  dynLooselySetState(key: string, value: string) {
    this.setState(prevState => ({
      ...prevState,
      [key]: value // No error here, but can't ensure that key is in StateKeys
    }));
  }

Π‘Π°ΠΌΡ‹ΠΉ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π­Ρ‚ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ самого компилятора, Ρ‚ΠΈΠΏΡ‹, Π²Ρ‹Π²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ вычислСнных ΠΊΠ»ΡŽΡ‡Π΅ΠΉ свойств, Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ‚ΠΈΠΏΡ‹ объСдинСния, ΠΎΠ½ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ string , number , symbol ΠΈΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ…. 3, Ссли ΠΎΠ½ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ это объСдинСниС любого ΠΈΠ· Π½ΠΈΡ…, ΠΎΠ½ просто ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π΅Π³ΠΎ Π² ΠΎΠ±Ρ‰ΠΈΠΉ Ρ‚ΠΈΠΏ string . ΠžΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ здСсь - ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

dynSetState(key: StateKeys, value: string) {
  this.setState({
    [key]: value
  } as Pick<State, keyof State>)
}

Π­Ρ‚ΠΎ всС Ρ€Π°Π²Π½ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ошибкС, Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π½Π°Π±ΠΎΡ€ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ свойств, Π½ΠΎ Π½Π΅ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ, Ссли ΠΊΠ»ΡŽΡ‡ΠΈ Π½Π΅ входят Π² Π½Π°Π±ΠΎΡ€ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ свойств.

ВсС 12 ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π­Ρ‚ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ самого компилятора, Ρ‚ΠΈΠΏΡ‹, Π²Ρ‹Π²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ вычислСнных ΠΊΠ»ΡŽΡ‡Π΅ΠΉ свойств, Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ Ρ‚ΠΈΠΏΡ‹ объСдинСния, ΠΎΠ½ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ string , number , symbol ΠΈΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ…. 3, Ссли ΠΎΠ½ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ это объСдинСниС любого ΠΈΠ· Π½ΠΈΡ…, ΠΎΠ½ просто ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π΅Π³ΠΎ Π² ΠΎΠ±Ρ‰ΠΈΠΉ Ρ‚ΠΈΠΏ string . ΠžΠ±Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡƒΡ‚ΡŒ здСсь - ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

dynSetState(key: StateKeys, value: string) {
  this.setState({
    [key]: value
  } as Pick<State, keyof State>)
}

Π­Ρ‚ΠΎ всС Ρ€Π°Π²Π½ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ошибкС, Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π½Π°Π±ΠΎΡ€ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ свойств, Π½ΠΎ Π½Π΅ выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ, Ссли ΠΊΠ»ΡŽΡ‡ΠΈ Π½Π΅ входят Π² Π½Π°Π±ΠΎΡ€ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΊΠ»ΡŽΡ‡Π΅ΠΉ свойств.

ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ @ferdaber, хотя IMHO Ρ‚Π°ΠΊΠΈΠ΅ Π²Π΅Ρ‰ΠΈ, ΠΊΠ°ΠΊ это, Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ "Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ шаблон", Π² Ρ†Π΅Π»ΠΎΠΌ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Π΅ΡΡ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ состояния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ шаблона ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ снова придСрТиваСтся Π»ΡƒΡ‡ΡˆΠΈΡ… ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ этого ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° Π²Π½Π΅ класса Π² Ρ‡ΠΈΡΡ‚ΡƒΡŽ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ для тСстирования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ :)

Π₯ΠΎΡ€ΠΎΡˆΠΈΠΉ:

class C extends Component<{}, State> {
  updateState(key: StateKeys, value: string) {
    this.setState((prevState) => ({
      ...prevState,
      [key]: value,
    }));
  }
}

Π›ΡƒΡ‡ΡˆΠ΅:

const updateState = <T extends string>(key: keyof State, value: T) => (
  prevState: State
): State => ({
  ...prevState,
  [key]: value
})

class C extends Component<{}, State> {
  doSomething(){
    this.setState(updateState('password','123124'))
  }
}

Π― Π½Π΅ нашСл связанной ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с этим ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ машинописного тСкста. Π•ΡΡ‚ΡŒ Π»ΠΈ шанс, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, ΠΎΠ±ΡΡƒΠΆΠ΄Π°Π»ΠΎΡΡŒ Π»ΠΈ это (ΠΈ Π³Π΄Π΅) Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ машинописного тСкста? Π’ основном интСрСсно, Π΅ΡΡ‚ΡŒ Π»ΠΈ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΏΠ»Π°Π½Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ Π² Π±ΡƒΠ΄ΡƒΡ‰ΠΈΡ… вСрсиях машинописного тСкста.
Бпасибо!

Π’ΠΎΡ‚ обсуТдСниС, примСчания ΠΏΠΎ Π΄ΠΈΠ·Π°ΠΉΠ½Ρƒ ΠΎΡ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ TS ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ это (ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅, ΠΊΠ°ΠΊ ΠΌΠ½Π΅ каТСтся, Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΎΠ·Π²Π°Π½ΠΎ для Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΉ вСрсии):
https://github.com/Microsoft/TypeScript/issues/13948
https://github.com/Microsoft/TypeScript/issues/18155
https://github.com/Microsoft/TypeScript/pull/21070

Π’ самом Π΄Π΅Π»Π΅, я ΠΏΡ‹Ρ‚Π°ΡŽΡΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π²Ρ€ΠΎΠ΄Π΅ этого: https://reactjs.org/docs/forms.html#handling -multiple-inputs
Π­Ρ‚ΠΎ упростит Ρ€Π°Π±ΠΎΡ‚Ρƒ с Ρ„ΠΎΡ€ΠΌΠΎΠΉ с нСсколькими Π²Ρ…ΠΎΠ΄Π°ΠΌΠΈ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΌΠ½Π΅ всС Π΅Ρ‰Π΅ придСтся ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ name - это Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ, Π½ΠΎ послС этого Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.

МнС ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ as unknown Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ @ferdaber :

  this.setState({
    [key]: value
  } as unknown as Pick<State, keyof State>)

Π­Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Π΅Ρ‚, Ссли key Π±Ρ‹Π»ΠΎ логичСским, Π½ΠΎ Π½Π΅ числом!

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я Π²Ρ‹Π±Ρ€Π°Π» это Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅:

  this.setState<never>({
    [key]: value
  })

Π­Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Π΅Ρ‚, являСтся Π»ΠΈ key логичСским ΠΈΠ»ΠΈ числом.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ https://github.com/DefinitiTyped/DefinitiTyped/issues/26635#issuecomment -400260278 Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚? Π― имСю Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ Ρ‚ΠΈΠΏ объСдинСния?

ΠœΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ это ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Π΅Π±Π΅

type IAction = {
  [P in keyof IAppSettings]?: IAppSettings[P];
};

function reducer(state: IAppSettings, action: IAction) {
  return {
    ...state,
    ...action,
  };
}

Π•ΡΡ‚ΡŒ Π»ΠΈ прогрСсс Π² этом вопросС?

Π― смог Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ это Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ

handleTextChange(name: keyof State, value: any) {
    this.setState({
        ...this.state,
        [name]: value
    });
}

Для Π΄Ρ€ΡƒΠ³ΠΈΡ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ смотрят Π½Π° это ΠΈ ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΊ своим собствСнным Ρ‚ΠΈΠΏΠ°ΠΌ состояний, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ value Π² исходном сообщСнии ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°Ρ… Ρ€Π°Π²Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ string ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ всС Ρ‚ΠΈΠΏΡ‹ свойств Π² State - это string . Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ использования any ΠΈΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ привСдСния, ΠΊΠΎΠ³Π΄Π° задСйствованы Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹, ΠΈ вмСсто этого ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΈΠΏ value соотвСтствовал Π΅Π³ΠΎ Ρ‚ΠΈΠΏΡƒ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Ρ‚ΠΈΠΏΡƒ ΠΊΠ»ΡŽΡ‡Π°.

interface State {
  name: string;
  age: number;
}
type StateKeys = keyof State;
function dynSetState<K extends StateKeys>(key: K, value: State[K]) {
  this.setState({ [key]: value }); // fails; if only this worked...
  this.setState({ [key]: value } as Pick<State, K>); // clean cast works
  this.setState((s, _) => ({ ...s, [key]: value })); // avoids cast, but changes js
}
dynSetState("name", "a"); // works as expected
dynSetState("name", 1); // fails as expected
dynSetState("age", "a"); // fails as expected
dynSetState("age", 1); // works as expected

ΠŸΠΎΡ‡Π΅ΠΌΡƒ # 26635 (ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ) Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚? Π― имСю Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ Ρ‚ΠΈΠΏ объСдинСния?

Π­Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ { ...prevState } Π±ΡƒΠ΄Π΅Ρ‚ Π² достаточной ΠΌΠ΅Ρ€Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ State , Π² основном ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ всС свойства состояния. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π±Π΅Π· Π½Π΅Π³ΠΎ _Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚_. ΠšΠΎΡ€Π΅Π½ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ созданного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°: { [key: K]: State[K] } нСдостаточно ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½; это { [x: string]: State[K] } ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ»ΡŽΡ‡ string Π² keyof State .

ΠŸΡ€ΠΎΡΡ‚ΠΎ добавлю Π²

TL; DR: ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ·Ρƒ

Π Π°ΡΡˆΠΈΡ€Π΅Π½Π½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ с ошибками консоли:

type RegisterTypes = {
    email: string;
    password: string;
}

// ...

const [state, setState] = useState<RegisterTypes>({
    email: "",
    password: "",
});

// ...

const onChangeInput = (key: keyof RegisterTypes) => (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({
        [key]: event.target.value
    } as Pick<RegisterTypes, typeof key>);
};

// ...

<input type="email" onChange={onChangeInput('email')} value={state.email} />

Π₯отя это Π΄Π°Π΅Ρ‚ ΠΌΠ½Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π² консоли:

Warning: A component is changing a controlled input of type password to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ (ΠΎΠ±ΠΌΠ°Π½) с ошибками консоли:

И Ρ‚ΠΎΠΆΠ΅ Π΄Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅.

type RegisterTypes = {
    [key: string]: string;
}

// ...

const onChangeInput = (key: string) => (event: React.ChangeEvent<HTMLInputElement>) => {
    setState({
        [key]: event.target.value
    });
};

ΠžΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π±Π΅Π· ошибок:

type RegisterTypes = {
    email: string;
    password: string;
}

// ...

const onChangeInput = (event: React.ChangeEvent<HTMLInputElement>) => {
    const newState = { ...state };
    newState[event.target.name as keyof RegisterTypes] = event.target.value;
    setState(newState);
};

// ...

<input name="email" type="email" onChange={onChangeInput} value={state.email} />
Π‘Ρ‹Π»Π° Π»ΠΈ эта страница ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ?
0 / 5 - 0 Ρ€Π΅ΠΉΡ‚ΠΈΠ½Π³ΠΈ