javascript - 如何修复错误“元素隐式具有‘任何’类型,因为类型的表达式
问题描述
我是 TypeScript 的初学者。
我曾经ts migrate
在我的 react 应用程序中用 TypeScript 替换 JavaScript,但出现以下错误。
Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'. TS7053
导致错误的文件如下。
import React, { useState, useEffect, useCallback} from 'react';
import './assets/styles/style.css';
import {AnswersList, Chats} from './components/index';
import FormDialog from './components/Forms/FormDialog';
import {db} from './firebase/index';
const App = () => {
const [answers, setAnswers] = useState([]);
const [chats, setChats] = useState([]);
const [currentId, setCurrentId] = useState("init");
const [dataset, setDataset] = useState({});
const [open, setOpen] = useState(false);
const displayNextQuestion = (nextQuestionId: any, nextDataset: any) => {
addChats({
text: nextDataset.question,
type: 'question'
})
setAnswers(nextDataset.answers)
setCurrentId(nextQuestionId)
}
const selectAnswer = (selectedAnswer: any, nextQuestionId: any) => {
switch(true) {
case (nextQuestionId === 'contact'):
handleClickOpen()
break;
case (/^https:*/.test(nextQuestionId)):
const a = document.createElement('a');
a.href = nextQuestionId;
a.target = '_blank';
a.click();
break;
default:
addChats({
text: selectedAnswer,
type: 'answer'
})
setTimeout(() => displayNextQuestion(nextQuestionId, dataset[nextQuestionId]), 500) //Here's where the error occurs
break;
}
}
const addChats = (chat: any) => {
setChats(prevChats => {
return [...prevChats, chat]
})
}
const handleClickOpen = () => {
setOpen(true)
};
const handleClose = useCallback(() => {
setOpen(false)
}, [setOpen]);
useEffect(() => {
(async() => {
const initDataset = {};
await db.collection('questions').get().then(snapshots => {
snapshots.forEach(doc => {
const id = doc.id
const data = doc.data()
initDataset[id] = data
})
})
setDataset(initDataset)
displayNextQuestion(currentId, initDataset[currentId])
})()
}, [])
useEffect(() => {
const scrollArea = document.getElementById('scroll-area')
if (scrollArea) {
scrollArea.scrollTop = scrollArea.scrollHeight
}
})
return(
<section className="c-section">
<div className="c-box">
<Chats chats={chats} />
<AnswersList answers={answers} select={selectAnswer} />
<FormDialog open={open} handleClose={handleClose} />
</div>
</section>
);
}
export default App;
首先,我定义了displayNextQuestion
使用接口的类型如下,但是错误没有解决,我们又得到了一个错误。
interface StringKeyObject {
[key: string]: any;
}
const displayNextQuestion: StringKeyObject = (nextQuestionId: any, nextDataset: any) => {
addChats({
text: nextDataset.question,
type: 'question'
})
setAnswers(nextDataset.answers)
setCurrentId(nextQuestionId)
}
This expression is not callable. Type 'StringKeyObject' has no call signatures. TS2349
接下来,displayNextQuestion
' 的参数nextQuestionId
是任何类型的,所以我将它设置为字符串,但错误没有改变。
我做了很多研究,不知道如何解决这个错误,所以我问。
解决方案
当你说:
const displayNextQuestion: StringKeyObject = (...)
这意味着显然不是displayNextQuestion
类型。StringKeyObject
这是一个功能。您也没有从此函数返回任何内容,因此返回类型也是void
如此。
现在让我们看看参数。nextQuestionId
必须是 astring
因为你使用setCurrentId(nextQuestionId)
它的默认状态是init
.
nextDataset
应该是一个具有一系列答案的对象,例如:
{
answers: [...],
...
}
将它们放在一起应该可以:
const displayNextQuestion = (nextQuestionId: string, nextDataset: { answers: Array<Answer> } ) => {
addChats({
text: nextDataset.question,
type: 'question'
})
setAnswers(nextDataset.answers)
setCurrentId(nextQuestionId)
}
我建议您为数据集定义一个接口以及answer
:
interface Answer {
// ...whatever that answer has
}
interface Dataset {
answers: Array<Answer>;
// ...other things that Dataset has
}
并明确设置类型useState
:
interface Question {}
interface Chat {}
interface Answer { }
interface Dataset {
answers: Array<Answer>;
question: any;
[k: string]: Question;
// ^ This signifies that Dataset can have any key as long as it's string
// and its value is of type Question (best I could guess based on the
// usage at "dataset[nextQuestionId])"
}
const App = () => {
const [answers, setAnswers] = useState<Array<Answer>>([]);
const [chats, setChats] = useState<Array<Chat>>([]);
const [currentId, setCurrentId] = useState("init");
const [dataset, setDataset] = useState<Dataset>({ answers: [], question: null });
const [open, setOpen] = useState(false);
// ...
推荐阅读
- android - Android SoundPool 不播放 wav 格式的声音
- mysql - 获得电影类型和演员阵容的输出
- angular - 使用一个可观察对象的输出作为另一个可观察对象的输入的正确方法是什么?
- version-control - 如何更新
在使用 Gulp 的前端工具包中的 nuspec 文件中? - python - Google AppEngine:部署 Flask 应用程序时出现 502 Bad Gateway
- sql - 如何将两列中的值子串到新列并更改顺序?
- python - 如何去除尾随零的整数
- python - 忽略spacy deprecation_warning
- regex - 为什么此代码跳过所有其他输入行
- python - 如何获取按与特定对象相交标签数量排序的查询集?