如何在打字稿中为匿名函数编写函数类型定义?
How to write function type definitions for anonymous functions in typescript?
我在我的 react-native(typescript) redux 项目中使用 redux-thunk。我正在使用 thunkWithExtraArgument Helper 来提供我的 apollo 客户端变量的引用,因为我得到了 return 函数的三个参数,即
...
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 => {
...
}
}}
您应该能够使用 contextual typing 为您推断参数类型,方法是让编译器意识到您需要 Thunk
类型的值。由于我没有 react/redux 打字(而且这个问题实际上是关于我认为的一般问题)我将使用一些编造的东西:
type Spronk = (x: string, y: number, z: boolean) => Promise<string>;
最类型安全的方法是注释这种类型的变量,return它:
const fethcSomeData = (id: string) => {
const ret: Spronk = async (x, y, z) => (z ? x : y.toFixed());
return ret;
};
或者您可以使用更简洁但不太安全的 type assertion(它会让您缩小值):
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
我已经注释 errorCaught
的类型为 Spronk
。编译器识别出我 returning string | number
而不是 string
,这意味着 errorCaught
不是真正的 Spronk
,而是 更宽类型。将变量注释为小于您分配给它的值是错误的。
const errorSuppressed = <Spronk>(async (x, y, z) => (z ? x : y)); // no error
在这里,我断言 errorCaught
的类型是Spronk
。编译器仍然识别出该值比 Spronk
宽,但是类型断言特别允许您说一个值的类型比编译器可以验证的更窄。有时这种灵活性很有用,但也很危险。在 errorSuppressed
的情况下,我们故意欺骗了编译器,这会给我们在运行时带来麻烦:
errorSuppressed("a", 1, false).then(s => console.log(s.charAt(0))); // compiles, but
// at runtime: "TypeError, s.charAt is not a function"
希望这是有道理的。
作为@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;
};
我在我的 react-native(typescript) redux 项目中使用 redux-thunk。我正在使用 thunkWithExtraArgument Helper 来提供我的 apollo 客户端变量的引用,因为我得到了 return 函数的三个参数,即
...
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 => {
...
}
}}
您应该能够使用 contextual typing 为您推断参数类型,方法是让编译器意识到您需要 Thunk
类型的值。由于我没有 react/redux 打字(而且这个问题实际上是关于我认为的一般问题)我将使用一些编造的东西:
type Spronk = (x: string, y: number, z: boolean) => Promise<string>;
最类型安全的方法是注释这种类型的变量,return它:
const fethcSomeData = (id: string) => {
const ret: Spronk = async (x, y, z) => (z ? x : y.toFixed());
return ret;
};
或者您可以使用更简洁但不太安全的 type assertion(它会让您缩小值):
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
我已经注释 errorCaught
的类型为 Spronk
。编译器识别出我 returning string | number
而不是 string
,这意味着 errorCaught
不是真正的 Spronk
,而是 更宽类型。将变量注释为小于您分配给它的值是错误的。
const errorSuppressed = <Spronk>(async (x, y, z) => (z ? x : y)); // no error
在这里,我断言 errorCaught
的类型是Spronk
。编译器仍然识别出该值比 Spronk
宽,但是类型断言特别允许您说一个值的类型比编译器可以验证的更窄。有时这种灵活性很有用,但也很危险。在 errorSuppressed
的情况下,我们故意欺骗了编译器,这会给我们在运行时带来麻烦:
errorSuppressed("a", 1, false).then(s => console.log(s.charAt(0))); // compiles, but
// at runtime: "TypeError, s.charAt is not a function"
希望这是有道理的。
作为@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;
};