[TS] Types - unknown, any, never

About

TypeScript has these three types that might be unfamiliar to JS users.

  • unknown

  • any

  • never

unknown - The "Top" Type

unknown is the top type of TypeScript. It can have any value that can exist, hence the superset of all types. But because of that, you can't use any operations except for those that all types can do in common. So the type is "unknown".

When using it, you need to specify the type. But if it's type guarded, you don't need to.

let val: unknown = 'hello'
val = 30
let age: number = val // error
let age: number = (val as number) // ok
const flag: unknown = true

if (flag === true) { // flag is a boolean from now on
  const something: boolean = flag
  // ...
}

const maybe: unknown = 'hello'
if (typeof maybe === 'string') {
  const text: string = maybe
}

any - The "Anything" Type

You can always satisfy your type check and use any value immediately.

You might use it when:

  • using a JavaScript module with minimal modifications

  • rewriting an existing JavaScript code into TypeScript

The code will always work without much effort. But on the contrary, it will always satisfy the type check, resulting in many side effects such as unintended type conversions or values.

let value: any = 42

value.runTask() // The compiler does not check whether value has the method or not
const user: any = {}
user.posts.orderBy('id')

never - The "Bottom" Type

never is the opposite of unknown. It's the subset of all types. Hence, no value can be assigned to a variable with never type.

const first: never = 42 // compile error
const second: never = 'some text' // compile error

You might be wondering if never will ever be used.

  • when function doesn't return any value

  • when removing type inference exceptions

  • etc...

Here, the fetchUserFriends is never returning a value.

function fetchUserFriends(username: string): never {
  throw new Error('Not implemented')
}

Use never to prevent from assigning certain type values. The NonString type can be any type. But if it's string, infer it as never to prevent from a string type value from being assigned to it.

type NonString<T> = T extends string ? never : T

Ok, How is this different from void?

As Marius Schulz discusses in this article,

  • A function that doesn't explicitly return a value implicitly returns the value undefined in JavaScript. Although we typically say that such a function "doesn't return anything", it returns. We usually ignore the return value in these cases. Such a function is inferred to have a void return type in TypeScript.

  • A function that has a never return type never returns. It doesn't return undefined, either. The function doesn't have a normal completion, which means it throws an error or never finishes running at all.

REF

All of the contents are from this:

Last updated