簡體   English   中英

如何在打字稿中為匿名函數編寫函數類型定義?

[英]How to write function type definitions for anonymous functions in typescript?

我在我的 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 => {
    ...
  }
}}

通過讓編譯器意識到您需要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

我已經注釋類型errorCaughtSpronk 編譯器識別出我正在返回一個string | number string | number ,而不是一個string ,這意味着errorCaught不是真正Spronk ,但更寬的類型。 將變量注釋為比分配給它的值更窄是錯誤的。

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

在這里,我斷言類型errorCaughtSpronk 編譯器仍然識別出該值比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; 
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM