简体   繁体   English

Typescript编译错误,即使参数的类型正确

[英]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.

相关问题 为什么即使代码正在检查未定义,typescript 仍会返回此编译错误? - why is typescript returning this compile error even though the code is checking for undefined? 即使语法正确也反应错误 - React error even though syntax is correct 打字稿编译错误:类型“ {}”不可分配给类型“ T” - Typescript Compile Error: Type '{}' is not assignable to type 'T' 反应错误:无效的钩子调用 - 即使语法似乎正确 - React Error: Invalid hook call - even though syntax seems correct 即使类型正确,Typescript 也会为错误的类型抛出错误 - Typescript throwing an error for the wrong type even when the type is right 即使返回的类型是对象,也无法访问对象属性 - React + Typescript - Can't access object property even though type of returns it is an object - React + Typescript 即使父级的初始值正确,为什么嵌套的子级子项上的“失败的道具类型”呢? - Why “Failed prop type” on nested cloned children, even though parent have correct initial values? 即使满足要求,RelayFindGraphQLTags 也无法编译 - RelayFindGraphQLTags failing to compile even though requirements are satisfied 打字稿没有读取正确的类型 - Typescript not reading the correct type 即使在tsconfig.json中排除了导入的react node_module中的Typescript编译错误 - Typescript compilation error in imported react node_module, even though it's excluded in tsconfig.json
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM