Я новичок в Typescript и пытаюсь использовать Redux-Toolkit с ним в своем приложении React. Здесь я пытаюсь создать приложение To Do с вложенным состоянием, где каждый ToDo
содержит массив Comment
. Вот интерфейсы:
Comment.ts
export interface Comment {
id: number;
comment: string;
}
ToDo.ts
export interface ToDo {
id: number;
title: string;
description: string;
comments: Array<Comment>;
}
Тогда в моем ToDoSlice
:
export const toDoSlice = createSlice({
name: 'toDoSlice',
initialState: [] as Array<ToDo>,
reducers: {
addToDo: (state, action: PayloadAction<ToDo> ) => {
state.push(action.payload);
},
}
});
Компилятор TS добавляет это в строку state.push(action.payload)
:
TS2345: Argument of type 'ToDo' is not assignable to parameter of type 'WritableDraft<ToDo>'.
Types of property 'comments' are incompatible.
Type 'Comment[]' is not assignable to type 'WritableDraft<Comment>[]'.
Type 'Comment' is not assignable to type 'WritableDraft<Comment>'.
The types of 'ownerDocument.all' are incompatible between these types.
Type 'HTMLAllCollection' is not assignable to type 'WritableDraft<HTMLAllCollection>'.
'number' index signatures are incompatible.
Type 'Element' is not assignable to type 'WritableDraft<Element>'.
Types of property 'attributes' are incompatible.
Type 'NamedNodeMap' is not assignable to type 'WritableDraft<NamedNodeMap>'.
'number' index signatures are incompatible.
Type 'Attr' is not assignable to type 'WritableDraft<Attr>'.
Types of property 'childNodes' are incompatible.
Type 'NodeListOf<ChildNode>' is not assignable to type 'WritableDraft<NodeListOf<ChildNode>>'.
'number' index signatures are incompatible.
Type 'ChildNode' is not assignable to type 'WritableDraft<ChildNode>'.
Types of property 'parentElement' are incompatible.
Type 'HTMLElement | null' is not assignable to type 'WritableDraft<HTMLElement> | null'.
Type 'HTMLElement' is not assignable to type 'WritableDraft<HTMLElement>'.
Types of property 'shadowRoot' are incompatible.
Type 'ShadowRoot | null' is not assignable to type 'WritableDraft<ShadowRoot> | null'.
Type 'ShadowRoot' is not assignable to type 'WritableDraft<ShadowRoot>'.
Types of property 'adoptedStyleSheets' are incompatible.
Type 'CSSStyleSheet[]' is not assignable to type 'WritableDraft<CSSStyleSheet>[]'.
Type 'CSSStyleSheet' is not assignable to type 'WritableDraft<CSSStyleSheet>'.
Types of property 'ownerNode' are incompatible.
Type 'Element | ProcessingInstruction | null' is not assignable to type 'WritableDraft<Element> | WritableDraft<ProcessingInstruction> | null'.
Type 'ProcessingInstruction' is not assignable to type 'WritableDraft<Element> | WritableDraft<ProcessingInstruction> | null'.
Я попытался привести action.payload
к типу WritableDraft<ToDo>
, и ошибка исчезла.
addToDo: (state, action: PayloadAction<ToDo> ) =>
{state.push(action.payload as WritableDraft<ToDo>);
},
Однако аналогичная проблема возникает, когда я пытаюсь добавить Comment
в существующий ToDo
:
addComment: (state, action: PayloadAction<{toDoId: number, comment: Comment}>) => {
const toDo = state.find(toDo => toDo.id === action.payload.toDoId);
if (toDo) {
toDo.comments.push(action.payload.comment);
}
}
где выдает другую ошибку:
Argument of type 'Comment' is not assignable to parameter of type 'WritableDraft<Comment>'.
Type 'Comment' is missing the following properties from type 'WritableDraft<Comment>': data, length, ownerDocument, appendData, and 59 more.
и кастинг action.payload.comment as WritableDraft<Comment>
не подойдет. Ошибка почти осталась прежней.
Версия зависимостей внутри package.json
:
"dependencies": {
"@reduxjs/toolkit": "^1.9.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.4.3",
"react-scripts": "5.0.1",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0"
},
Спасибо за ответ, теперь я отредактировал сообщение, чтобы показать версии внутри package.json
. Typescript сообщил об этой ошибке в строке state.push(action.payload)
, когда я еще не написал никакой логики диспетчеризации
После использования вашего package.json я все еще не вижу ошибок машинописного текста. Можете ли вы создать минимальный рабочий пример с помощью песочницы, такой как codeandbox.io, чтобы было легко определить проблему в вашем коде?
Конечно. Вот коды и коробка: codeandbox.io/s/gifted-bouman-5q2qm2. Если вы откроете toDoSlice.ts
в каталоге src/redux
, вы увидите красную волнистую линию в строках 14 и 25. Как ни странно, приложение отлично работает в codeandbox, но не на моем локальном компьютере, я думаю, что codeandbox строго не проверяет Typescript, потому что, если Я меняю state.toDoList.push(action.payload);
на что-то вроде state.toDoList.push(action.payload.notexist)
, приложение по-прежнему работает нормально (хотя с волнистыми линиями, указывающими на ошибку)
вы должны написать это:
reducers: {
addToDo: (state, action: PayloadAction<ToDo> ) => {
state.push(action.payload as ToDo);
},
Спасибо за ответ, к сожалению, это не снимает проблему. Он по-прежнему сообщает о той же ошибке, как если бы я написал state.push(action.payload)
В файле ToDo.ts
внутри папки models
вам просто нужно импортировать интерфейс Comment
из Comment.ts
.
import { Comment } from './Comment'
Это исправит эту ошибку машинописного текста.
Боже мой, большое спасибо. Не могу поверить, что вся проблема связана с коллизией типов Comment
!
Я запускаю ваш код и не вижу ошибок машинописи. я проверил ваш код, используя реакцию v17.0.2 и redux-toolkit v1.5.1. Можете ли вы указать редукс-инструментарий и версию реакции? Я не уверен, но может машинописный текст выдает эту ошибку, когда вы пытаетесь отправить с неправильной полезной нагрузкой. Также здесь некорректно использовать тип WritableDraft.
state
внутри функции редуктора естьDraft
.