1

I am new in TypeScript. I want to pass the typescript's interface to react state and then render the state. But I don't know how to pass the interface value to react state.

import React, { useState } from 'react'

export interface Person {
  name: name
  age: age
}

type name = "John"
type age = 30
const Test = () => {

  const [state, setstate] = useState() //I want to pass the interface in here
  return (
    <div>
    <p> He is {state.name} and he is {state.age} years old</p> 
    </div>
  )
}
export default Test;
juha
  • 515
  • 5
  • 10
  • 18

2 Answers2

1

You create an object that matches the interface, and pass that into useState, like this:

const [state, setState] = useState({name: "John", age: 30});

You can also be explicit about the type of that state variable, because useState is generic:

const [state, setState] = useState<Person>({name: "John", age: 30});

but you don't have to be. TypeScript's type checking is structural, not nominal,¹ meaning that any object with appropriately-matching properties is a match for the state.

If you may not have a person, allow null or undefined:

const [state, setState] = useState<Person | null>(null);
// or
const [state, setState] = useState<Person | undefined>(undefined);

In that case, since the type would be null or undefined if it were just inferred from what you pass into useState, you need the generic type parameter on the call.


¹ For me, this concept was foundational in TypeScript. It's not so much that something is a type as it is in (say) Java, it's that something matches a type. This is perfectly valid TypeScript:

interface A {
    name: string;
    age: number;
}
interface B {
    name: string;
    age: number;
}
let a: A = {name: "Joe", age: 27};
let b: B;
b = a;

It doesn't matter that b is declared as type B and a is declared as type A, you can do b = a; because a's type is structurally compatible with b's type (in this case, they're identical).

This is also perfectly valid:

interface A {
    name: string;
    age: number;
    rank: string;
}
interface B {
    name: string;
    age: number;
}
let a: A = {name: "Joe", age: 27, rank: "Junior Petty Officer"};
let b: B;
b = a;

It's okay that a's type has a property (rank) that b's type doesn't have. It's still compatible with b's type.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • *(Doh! Of course this is a duplicate question. Since I'd already done the answer, I've marked it a community wiki rather than deleting it.)* – T.J. Crowder May 06 '20 at 07:01
0

You can define the interface type with useState like

const [state, setstate] = useState<Person>({name: "John", age: 30 });

Be sure to provide the intialState according to Person type property. If instead you define an empty object you could write it like

const [state, setstate] = useState<Person>(Object);

Also you could specify useState type to be null or undefined by explicitly defining it

const [state, setstate] = useState<Person | undefined>();

and

const [state, setstate] = useState<Person | null>(null);
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400