2

我在我的 react-native(typescript) redux 项目中使用 redux-thunk。我正在使用 thunkWithExtraArgument Helper 来提供我的 apollo 客户端变量的引用,因为我得到了返回函数的三个参数,即

...
return async (dispatch, getState, client) => 
...
// and with typescript
import { NormalizedCacheObject } from 'apollo-cache-inmemory'
import ApolloClient from 'apollo-client'
import { Dispatch } from 'redux'

import { ReduxStore } from '../interfaces/redux.ts';

...
return async (dispatch: Dispatch, getState: () => ReduxStore, client: ApolloClient<NormalizedCacheObject>): Promise<void>) => {
...
}

我必须在任何地方都输入很多代码,所以有什么解决方案吗?

目前,我正在做的是:


import { NormalizedCacheObject } from 'apollo-cache-inmemory'
import ApolloClient from 'apollo-client'
import { Dispatch } from 'redux'
import { ReduxStore } from '../interfaces/redux.ts'

// actually i outsources both GetState and Client types
type GetState = () => ReduxStore
// where ReduxStore is custom defined interface
type Client = ApolloClient<NormalizedCacheObject>

const fetchSomeData = (id: string) => {
  return async (dispatch: Dispatch, getState: GetState, client: Client): Promise<void>) => {
    ...
  }
}

我尝试过并且需要的是

...
export type Thunk = (dispatch: Dispatch, getState: () => ReduxStore, client: ApolloClient<NormalizedCacheObject>): Promise<void>
...

// action creator

const fethcSomeData = (id: string) => {
  return async (dispatch, getState, client): Thunk => {
    ...
  }
}}

4

2 回答 2

2

通过让编译器意识到您需要一个 type 的值,您应该能够使用上下文Thunk类型为您推断参数类型。由于我没有 react/redux 类型(问题实际上是关于我认为的一般问题),我将使用一些编造的东西:

type Spronk = (x: string, y: number, z: boolean) => Promise<string>;

最安全的方法是注释此类型的变量并返回它:

const fethcSomeData = (id: string) => {
  const ret: Spronk = async (x, y, z) => (z ? x : y.toFixed());
  return ret;
};

或者您可以使用更简洁但不太安全的类型断言(它可以让您缩小值):

const fthecSomeData = (id: string) => {
  return <Spronk>(async (x, y, z) => (z ? x : y.toFixed())); 
};

无论哪种方式都应该对你有用。祝你好运!


更新:这就是我所说的不安全的意思。以下是一个错误:

const errorCaught: Spronk = async (x, y, z) => (z ? x : y); // error!
// (string | number) is not assignable to string

我已经注释errorCaughtto be的类型Spronk。编译器识别出我返回的是 astring | number而不是 a string,这意味着它errorCaught不是 true Spronk,而是更广泛的类型。将变量注释为比您分配给它的值更窄是错误的。

const errorSuppressed = <Spronk>(async (x, y, z) => (z ? x : y)); // no error

在这里,我断言errorCaught了to的类型Spronk。编译器仍然承认该值比 a 宽Spronk,但类型断言特别允许您说一个值的类型比编译器可以验证的窄。有时这种灵活性很有用,但也很危险。如果errorSuppressed我们故意对编译器撒谎,这会给我们在运行时带来麻烦:

errorSuppressed("a", 1, false).then(s => console.log(s.charAt(0))); // compiles, but
// at runtime: "TypeError, s.charAt is not a function"

希望这是有道理的。

链接到代码

于 2019-08-19T19:23:06.230 回答
0

作为@jcalz 的第二个选项类型断言,现在最新的打字稿编译器警告这一点

Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead

所以以这种方式使用它是可取的


const fetchSomeData = (id: string) => {
  return <Spronk>(async (x, y, z) => (z ? x : y.toFixed())); 
};

to

const fetchSomeData = (id: string) => {
  return (async (x, y, z) => (z ? x : y.toFixed())) as Spronk; 
};
于 2019-08-19T19:39:32.667 回答