3

enter image description here

As can be seen in the image, I want to declare a react state hook to the alert of my webpage. At first, I want that there is no alert shown. And whenever user is clicking some button, I want to show a success alert with a message (error alert if something goes wrong). I will call showAlert function to do this with message and type as function parameter. That's why there can be more than one type of alert. So, I created this alert object and attached hook with initial value "NULL". But the editor gives me this error.

Argument of type '{ msg: any; type: any; }' is not assignable to parameter of type 'SetStateAction<null>'. Object literal may only specify known properties, and 'msg' does not exist in type '(prevState: null) => null'.ts(2345)

So, can someone tell me how I can tell useState the object parameters that I will allot it in future. Or should I try to hide the website alert in some other way? Here is the code..

const [alert, setAlert] = useState(null);

const showAlert = (message, type) => {
    setAlert({
        msg: message,
        type: type,
    });

    setTimeout(() => {
        setAlert(null);
    }, 2000);

enter image description here

This solution is not working for me.

5
  • 1
    Please replace the image of code with a text-based minimal reproducible example Commented Jul 5, 2022 at 13:54
  • 1
    Define the type of the state useState(null as any) Commented Jul 5, 2022 at 13:55
  • 1
    useState<{msg: string, type: string}>(null). In case if you have strict null checks on in your tsconfig, you will not able to set null. Either you can remove that from tsconfig or you can useState<{msg: string, type: string} | null>(null) Commented Jul 5, 2022 at 13:56
  • @Rashomon I have tried that. I get these two erros. 1. Parsing error: Unexpected token, expected "," (10:41)eslint {squigly error on null word} 2. Type assertion expressions can only be used in TypeScript files.ts(8016) {error line under any word} Commented Jul 5, 2022 at 13:59
  • @Dilshan I am getting these errors for your solution. 1. Type 'number' must have a '[Symbol.iterator]()' method that returns an iterator.ts(2488) 2. (property) msg: any Operator '<' cannot be applied to types '{ <S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>]; <S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>]; }' and '{ msg: any; type: any; }'.ts(2365) The '|' operator is not allowed for boolean types. Consider using '||' instead.ts(2447) 3. Comparing to itself is potentially pointless.eslintno-self-compare Object is possibly 'null'.ts(2531) Commented Jul 5, 2022 at 14:01

4 Answers 4

4

From the looks of the error you mentioned, it seems you're using TypeScript.

One way to achieve the desired outcome is to use generics.

const [alert, setAlert] = useState<{
  msg: string;
  type: "success" | "error";
} | null>(null);

Furthermore, you can improve readability by adding an enum and a type.

enum AlertType {
  Success,
  Error,
}

type Alert = {
  msg: string;
  type: AlertType;
}

const [alert, setAlert] = useState<Alert | null>(null);
Sign up to request clarification or add additional context in comments.

2 Comments

I am using javascript only but it seems like I am getting typesript errors in javascript. Also the solution you gave will not work because type aliases and enum declarations aren't supported in javascript.
I've assumed that you're using TypeScript, hence the nature of the solution. You are correct, this will not work in a JavaScript context. @BittuJoshi , it seems that VSCode has implicit TS validation even for JS files. You can give this one a try.
3

You can do it below way for useState type

type AlertType = {
 msg: string;
 type: string; // you can specify enum also
}

const [alert, setAlert] = useState<AlertType|null>(null);

const showAlert = (message, type) => {
    setAlert({
        msg: message,
        type: type,
    });

    setTimeout(() => {
        setAlert(null);
    }, 2000);

1 Comment

'AlertType' is declared but never used.ts(6196) Type aliases can only be used in TypeScript files.ts(8008) I am using javascript
2

You need to declare your useState a little differently

const [alert, setAlert] = useState<{ msg: any; type: any } | null>(null);

Another alternative is the use undefined

const [alert, setAlert] = useState<{ msg: any; type: any } | undefined>();

Hope that helps.

1 Comment

Operator '<' cannot be applied to types '{ <S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>]; <S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>]; }' and '{ msg: any; type: any; }'.ts(2365) ----The '|' operator is not allowed for boolean types. Consider using '||' instead.ts(2447) ----'any' only refers to a type, but is being used as a value here.ts(2693)-----Object is possibly 'null'.ts(2531)
1

There are 2 solutions:

1: useState(null as any)
2: useState({ msg: any, type: any })

1 Comment

1. Parsing error: Unexpected token, expected "," (10:41)eslint {error line under null} and Type assertion expressions can only be used in TypeScript files.ts(8016) {error line under any} 2. 'any' only refers to a type, but is being used as a value here.ts(2693) 'any' is not defined.eslintno-undef

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.