0
votes

Transmettre setState en tant que paramètre Typescript

Tenez compte de ce qui suit:

someFunction(setState) // pass
someFunction(setAnotherState) // fail
someFunction(anotherFunctions) // fail
someFunction() // fail
someFunction(0) // fail
someFunction(true) // fail
someFunction({}) // fail

Est-il possible de faire en sorte que someFunction n'accepte que ce setState code> fonction comme paramètre Ð °? Si oui, comment cela pourrait-il être fait?

Pour être clair, je veux:

// external file

export const someFunction = setState => {
    setState({ value: "some new string" })
} 

// component's file

import { someFunction } from "pathToFile"

interface TState {
    value: string
}

const [state, setState] = useState<TState>({ value: "some string" })

useEffect(() => {
   someFunction(setState)
}, [])


5 commentaires

Par «échec», voulez-vous dire que vous voulez que dactylographié renvoie une erreur de type lors de la transpilation?


@Swayam Oui, c'est ce que je voulais dire


Si j'ai bien compris, useState est tapé pour accepter un objet avec la clé "valeur" dont la valeur est une chaîne. C'est tout


Si, par exemple, j'autorise la deuxième option avec setAnotherState - toujours pas possible?


Je me suis trompé, la réponse de bela53 est correcte et résout magnifiquement ce problème


3 Réponses :


0
votes

Vous pouvez définir un type de paramètre très spécifique pour someFunction , qui vous donnera le même succès / échec que vous le souhaitez.


0 commentaires

0
votes

Vous pouvez atteindre votre objectif en implémentant les méthodes de rappel.

Exemple:

this.readStudentFile(anyFile, this.callback);

callback(isPass) {
 this.setState({ isPass: isPass });
}

readStudentFile(file: File, callback) {
 if(file) {
   callback(true);
 } else callback(false);
}


0 commentaires

2
votes

En gros, vous demandez un type nominal :

someFunction(setState) // pass
someFunction(setAnotherState) // fail
someFunction() // fail
someFunction(0) // fail
someFunction(true) // fail
someFunction({}) // fail
someFunction((...arg: any[]) => any) // fail

Désormais, les tests se comportent comme vous le souhaitez: P>

type NominalSetState = React.Dispatch<React.SetStateAction<TState>> &
  { readonly __brand_setState__: unique symbol }

const someFunction = (setState: NominalSetState) => {
    setState({ value: "some new string" })
}

function useNominalState(init: TState) {
    return useState<TState>(init) as [TState, NominalSetState]
}

const [state, setState] = useNominalState({ value: "some string" })
const [anotherState, setAnotherState] = useState<TState>({ value: "some string" })


3 commentaires

Je ne vois pas de raison pour laquelle les types nominaux ne devraient pas y fonctionner (bien que n'ayant parcouru que le post lié). En fin de compte, un type de marque n'est qu'une intersection avec un type aussi unique que possible. Vous pouvez ajuster NominalSetState à vos besoins.


J'ai encore du mal à trouver comment modifier NominalSetState , au cas où je passe une fonction supplémentaire après InitialState . Comment modifier NominalSetState pour ce type d'utilisation?


Veuillez publier un exemple de code de jeu minimal qui reproduit exactement votre problème / erreur.