json - 類型 '{}' 無法分配給類型 'IntrinsicAttributes & IntrinsicClassAttributes'
我目前正在製作一個簡單的 React 應用程式。這是我的 index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(
<App />,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
這裡我有我的 app.tsx
import * as React from 'react';
import SearchBar from '../containers/price_search_bar';
interface Props {
term: string;
}
class App extends React.Component<Props> {
// tslint:disable-next-line:typedef
constructor(props) {
super(props);
this.state = {term: '' };
}
render() {
return (
<div className="App">
<div className="App-header">
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
this is my application.
</p>
<div>
<form>
<SearchBar term={this.props.term} />
</form>
</div>
</div>
);
}
}
export default App;
還有我的搜尋欄容器:
import * as React from 'react';
interface Props {
term: string;
}
// tslint:disable-next-line:no-any
class SearchBar extends React.Component<Props> {
// tslint:disable-next-line:typedef
constructor(props) {
super(props);
this.state = { term: '' };
}
public render() {
return(
<form>
<input
placeholder="search for base budget"
className="form-control"
value={this.props.term}
/>
<span className="input-group-btn" >
<button type="submit" className="btn btn-secondary" >
Submit
</button>
</span>
</form>
);
}
}
export default SearchBar;
最後我有了我的 tsconfig.json:
{
"compilerOptions": {
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": false,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"node_modules/@types"
],
"noUnusedLocals": true
},
"exclude": [
"node_modules",
"build",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts"
]
}
我不斷遇到一個又一個的錯誤,每當我修正一個錯誤,另一個錯誤就會出現,我不確定自己做了什麼會讓它這樣。這是最新的錯誤:
./src/index.tsx
(7,3): error TS2322: Type '{}' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<App> & Readonly<{ children?: ReactNode; }> & Reado...'.
Type '{}' is not assignable to type 'Readonly<Props>'.
Property 'term' is missing in type '{}'.
我試著透過修改我的 tsconfig.json 來修復它,但同樣的錯誤仍然出現,我做錯了什麼,為什麼 TypeScript 會這樣出錯。我對這個很陌生,透過這個範例我正在嘗試了解 React 是如何運作的。
答案#1
我解決了很多「not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes'」類型的錯誤(微軟已關閉該問題),方法是聲明一個整個傳遞給組件的對象。
根據原作者的範例,不要使用 term={this.props.term},使用 {...searchBarProps} 來使它運作如下:
render() {
const searchBarProps = { // make sure all required component's inputs/Props keys&types match
term: this.props.term
}
return (
<div className="App">
...
<div>
<form>
<SearchBar {...searchBarProps} />
</form>
</div>
</div>
);
}
答案#2
你所需要做的就是正確聲明元件類型以包含 props 類型:
interface IMyProps {
myValue: boolean,
}
const MyComponent: React.FC<IMyProps> = (props: IMyProps) => {
...
}
export default MyComponent;
然後你可以這樣使用它:
import MyComponent from '../MyComponent';
...
return <MyComponent myValue={true} />
瞧,TypeScript 現在很高興。好處是 TypeScript 現在會檢查只傳遞 props 介面中實際存在的參數(可以防止拼寫錯誤等等)。
對於標準元件,它會類似於(已經在 Swapnill 的範例中出現的):
class MyComponent extends React.Component<IMyProps, IMyState>{
constructor(props: IMyProps){}
}
export default MyComponent;
答案#3
這裡的問題不是出在你的 tslint 設定上。看看以下的程式碼片段:
interface SearchBarProps {
term: string;
optionalArgument?: string;
}
interface SearchBarState{
something: number;
}
class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
constructor(props: SearchBarProps){
super(props);
this.state = {
something: 23
};
}
render() {
const {something} = this.state;
return (
<div>{something}</div>
)
}
}
在 class SearchBar extends React.Component<SearchBarProps, SearchBarState> { 中,SearchBarProps 和 SearchBarState 分別表示組件 SearchBar 預期的 props 類型和 state 類型。當你使用 TypeScript 時,必須給出 propTypes 和 stateType。
你可以使用關鍵字 any 來避免指定類型,但如果你真的想充分利用 TypeScript,我強烈建議你不要走這條“邪惡”的路。就你的情況而言,似乎你沒有指定 state 的類型卻使用了它,修正這一點就能解決這個問題。
編輯 1
在介面 SearchBarProps 中,當我們在 optionalArgument 前加上問號 ? 時,它就變成一個可選參數,因此即使你沒有明確傳遞 optionalArgument,<SearchBar term='some term' /> 也不會顯示任何錯誤。
希望這能解決你的問題!
