即使参数的类型正确,打字稿也会编译错误

时间:2019-04-26 22:19:03

标签: reactjs typescript redux react-redux

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函数时,才会引发该错误,但不需要在参数的定义中提供默认值。那么为什么打字稿会这样呢?这是设计使然吗?

1 个答案:

答案 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,满足编译器的要求。