Typescript抛出此编译错误:
Argument of type '(state: string, action: Action<string>) => string' is not assignable to parameter of type 'Reducer<string, Action<string>>'.
Types of parameters 'state' and 'state' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'. TS2345
我的函数如下:
function todos(state: string, action: Action<string>)
我不明白的是,首先,state
参数不可为空,但编译器说它为可为空。其次,错误消息在第一行说该函数的类型为(state: string, action: Action<string>) => string
(正确),而第三行说该第一个参数为string | undefined
!
我刚刚开始学习打字稿和react-redux,所以我真的很困惑。
编辑:
此外,我尝试调用传递undefined
作为第一个参数的函数,但编译器抱怨它不能按预期实现为空,但后来却抱怨它为可以为空!
编辑2
我忘了说我在使用todos
来从redux调用createStore
函数时使用createStore(todos)
函数。
完整的代码是这样的:
import React from 'react';
import ReactDOM from 'react-dom';
import './styles/index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {Action, createStore} from 'redux'
import {Provider} from "react-redux";
function todos(state: string, action: Action<string>) {
return state
}
let store = createStore(todos); // PROBLEM HERE
let app = (
<Provider store={store}>
<App/>
</Provider>
)
ReactDOM.render(app, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers:
serviceWorker.unregister();
此外,我知道通常使用combineReducers
,而state
不应是string
,但我出于好奇心而问这个问题(打字稿初学者),因为我知道有明显的解决方法。
我也尝试使用string[]
作为状态类型,但是抛出了相同的错误,只是此时的状态为string[] | undefined
。
编辑3:
我意识到,如果我向状态添加默认值,例如function todos(state: string = "", action: Action)
,错误将消失。但是为什么呢?鉴于状态已经是必需的,不可为空的参数,这不是多余的吗?在Swift和Kotlin中,仅当您使用nil状态参数调用todos
函数时,才会引发该错误,但不需要在参数的定义中提供默认值。那么为什么打字稿会这样呢?这是设计使然吗?
答案 0 :(得分:1)
回答EDIT 3中提到的确切问题,将函数参数设置为默认值(就像您通过为.wal
指定默认值所做的那样)将此类参数的类型更改为state
(在您的情况下)。这也等同于参数后的问号。所以下面三个函数的调用签名是相同的
string | undefined
我建议使用chapter来自Typescript文档的文件。
本主题开头的错误指出function todos(state: string | undefined, action: Action<string>)
function todos(state?: string, action: Action<string>) // This example is not completly correct as you should make action optional too, by addint ? to it name
function todos(state: string = "", action: Action<string>)
,因此,向Type 'string | undefined' is not assignable to type 'string'.
添加默认值会使它的类型为state
,满足编译器的要求。