[英]Typescript compile error even though parameters are of the correct type
Typescript throws this compile error: 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
and my function looks like this: 我的函数看起来像这样:
function todos(state: string, action: Action<string>)
What I can't understand is, first, the state
parameter is not nullable yet the compiler says it's nullable. 我不明白的是,首先,
state
参数不可为空,但编译器说它为可为空。 Second, the error message contradicts itself by saying in the first line that the function's type is (state: string, action: Action<string>) => string
(which is correct) whereas the third line is saying that the first parameter is string | undefined
其次,错误消息与第一行说函数的类型是
(state: string, action: Action<string>) => string
(正确)相反,而第三行则说第一个参数是string | undefined
string | undefined
! string | undefined
!
I'm just beginning learning typescript and react-redux so I'm really confused. 我只是开始学习打字稿和react-redux,所以我真的很困惑。
EDIT: 编辑:
Further, I tried calling the function passing undefined
as first argument but the compiler complains that it's not nullable as expected, yet complain later that it's nullable! 此外,我尝试调用传递
undefined
的函数作为第一个参数,但是编译器抱怨它不能按预期那样为空,但后来却抱怨它为空!
EDIT 2 编辑2
I forgot to say that I'm using the todos
function in calling the createStore
function from redux like this: createStore(todos)
. 我忘了说我在从redux调用
createStore
函数时使用了todos
函数,例如: createStore(todos)
。
The full code is this: 完整的代码是这样的:
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();
Also, I'm aware that combineReducers
is normally used and that state
shouldn't be a string
, but I'm asking this question purely out of curiosity (being a beginner in typescript) because I know that there are obvious workarounds. 另外,我知道通常使用
combineReducers
并且state
不应该是string
,但是我出于好奇(纯粹是打字稿的初学者)问这个问题,因为我知道有一些明显的解决方法。
I also tried using string[]
as the type of the state but same error is thrown except that it's string[] | undefined
我也尝试使用
string[]
作为状态的类型,但是抛出了相同的错误,只是它是string[] | undefined
string[] | undefined
at this time. string[] | undefined
。
EDIT 3: 编辑3:
I realized that if I add a default value to the state, eg function todos(state: string = "", action: Action)
, the error will be gone. 我意识到,如果我向状态添加默认值,例如
function todos(state: string = "", action: Action)
,该错误将消失。 But why is this? 但是为什么呢? Isn't it redundant given that state is already a required, non-nullable parameter?
鉴于状态已经是必需的,不可为空的参数,这不是多余的吗? In Swift and Kotlin, the error will be thrown only if you call the
todos
function with a nil state argument, but you don't need to provide a default value in the definition of the parameter. 在Swift和Kotlin中,仅当您使用nil状态参数调用
todos
函数时,才会引发错误,但不需要在参数的定义中提供默认值。 So why is this the case in typescript? 那么为什么打字稿会这样呢? Is this by design?
这是设计使然吗?
Answering your exact question mentioned in EDIT 3 making function parameter default (as you did by specifing default value for state
) changes type of such parameter to string | undefined
回答您在EDIT 3中提到的确切问题,将函数参数设置为默认值(就像您通过指定
state
默认值所做的那样),将此类参数的类型更改为string | undefined
string | undefined
(in your case). string | undefined
(根据您的情况)。 This also eqvivalent to question mark after parameter. 这也等同于参数后的问号。 So call signatures of three functions below are the same
所以下面三个函数的调用签名是相同的
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>)
I suggest this chapter from Typescript doc. 我建议使用Typescript文档中的这一章 。
Error in the start of this topic states that Type 'string | undefined' is not assignable to type 'string'.
本主题开头的错误指出
Type 'string | undefined' is not assignable to type 'string'.
Type 'string | undefined' is not assignable to type 'string'.
So adding default value to state
makes it of type string | undefined
因此,将默认值添加到
state
使其成为string | undefined
类型string | undefined
string | undefined
which satisfied compiler. string | undefined
哪个编译器满意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.