Установить тип состояния компонента React с помощью TypeScript - PullRequest
3 голосов
/ 28 апреля 2020

Я пытаюсь использовать TypeScript в моем React проекте


export enum IngridientType {
  BreadBottom = "BreadBottom",
  BreadTop = "BreadTop",
  Meat = "Meat",
  Cheese = "Cheese",
  Bacon = "Bacon",
  Salad = "Salad",
  Seeds1 = "Seeds1",
  Seeds2 = "Seeds2",
}

export type IngredientsListType<R> = { [key in keyof typeof IngridientType]?: R };

type IBurgerBuilderState<T> = { ingredients: IngredientsListType<T> };

class BurgerBuilder extends Component<{}, IBurgerBuilderState<number>> {
  state = {
    ingredients: {
       [IngridientType.Bacon]: 2,
       [IngridientType.Cheese]: 2,
    },
  };

...
}

, но получаю ошибку

Свойство 'state' в типе 'BurgerBuilder' нельзя назначить одному и тому же свойству в базовом типе «Component <{}, IBurgerBuilderState, any>». Тип '{ингридиенты: {[IngridientType.Salad]: число; [IngridientType.Cheese]: число; }; } 'нельзя присвоить типу «Только чтение».

Я не совсем понимаю, в чем здесь проблема ..

Ответы [ 2 ]

1 голос
/ 28 апреля 2020

Я настраивал игровую площадку TypeScript с вашим кодом и придумал следующий подход - использовал ваш enum вместе с простым generic type:

export enum IngridientType {
  BreadBottom = "BreadBottom",
  BreadTop = "BreadTop",
}

type IngridientsType<T extends string, U> = {
    [K in T]: U;
};

interface IState {
  ingredients: IngridientsType<IngridientType, number>;
}

const state: IState = {
  ingredients: {
    [IngridientType.BreadTop]: 0,
    [IngridientType.BreadBottom]: 2,
    someOtherIngredient: 'wrongType', // ts will throw errors on it
  }
}

Edit : если вы спросите меня, что является причиной ошибки в вашем примере, я не уверен на 100%. Однако приведенный выше пример может быть немного более дружественным ?

0 голосов
/ 28 апреля 2020
export enum IngridientType {
  BreadBottom = 'BreadBottom',
  BreadTop = 'BreadTop',
  Meat = 'Meat',
  Cheese = 'Cheese',
  Bacon = 'Bacon',
  Salad = 'Salad',
  Seeds1 = 'Seeds1',
  Seeds2 = 'Seeds2',
}

export type IngredientsListType<R> = Record<IngridientType, R>

type IBurgerBuilderState<T> = { ingredients: Partial<IngredientsListType<T>> }

export class BurgerBuilder extends Component<{}, IBurgerBuilderState<number>> {
  state = {
    ingredients: {
      [IngridientType.Bacon]: 2,
      [IngridientType.Cheese]: 2,
    },
  }
}

Поскольку вы инициализируете свое состояние только с частичным набором, вам нужно будет использовать Partial. Также ваш IngredientsListType может быть упрощен с помощью Record.

Примечание: Ingridient должно быть написано Ingredient

https://codepen.io/drGreen/details/wvKeNyB

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...