import { useEffect, useState } from 'react'
export type TTOrigin = {
name: 'Name1' | 'Name2'
url: string
}
export function App() {
const [data, setData] = useState<TTOrigin[]>([])
useEffect(() => {
fetch('https://swapi.dev/api/people/1/')
.then((res) => res.json())
.then((json) => setData(json))
.catch((err) => console.log(err))
}, [])
return <h1>App</h1>
}
JSON has type any. But TS allows to put it in setData. Although in useState the type TTOrigin is specified
2
Answers
The rule in Typescript is that no type checks are done on code that involves a variable of type
any
.It basically means that for all such code parts, Typescript will behave as JavaScript and the developer is responsible again for doing type checks (is this really an array / string / number), content checks (is this string really only "Y" or "N"), property name checks and what not.
The example code below runs and will show that the string variable
a
can suddenly contain a number3
:TS Playground: https://www.typescriptlang.org/play/?#code/FAGwpgLgBAhgXFAzhATgSwHYHMoF4oBEAHgaJFAEYIwYCeeUAzMDAxQNzADGA9hoj3AA6EDywAKGAEpufAcNESItAA5geAM1gzgwIA
any
is a special type in TypeScript because it is assignable to anything and can be assigned to anything. Simply put,any
turns off type checks. That’s why you can passjson
tosetData()
without compiler error.Regarding "Can we do a check for any?".
Yes, you can using a conditional type. Since
any
will allow any assignment you can check if two unassignable values will be assignable when intersected withany
. See jcalz’ great answer on the question Typescript check for the ‘any’ type. The following will raise a compiler error ifjson
is of typeany
by returningunknown
.Many people consider
fetch
unsafe because it returnsPromise<any>
. So you might also consider overriding the global definition with interface declaration merging.With the above declaration added, it will require you to assert the
json
value before assigning it.