Execute Program

Everyday TypeScript: Any

Welcome to the Any lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • TypeScript has a special type called any. It means what it sounds like: a variable with this type can hold any value at all.

  • >
    const n: any = 5;
    n;
    Result:
    5Pass Icon
  • >
    const s: any = 'five';
    s;
    Result:
    'five'Pass Icon
  • A value with the any type can be assigned to any variable, regardless of the variable's type.

  • >
    const n: any = 5;
    const n2: number = n;
    n2;
    Result:
    5Pass Icon
  • You might ask yourself why we haven't told you this earlier. It makes everything so easy!

  • Yes, but it also prevents the type system from ensuring that variables have the types that we think they have. All bets are off when you use any. For example, we can put a number in an any, then assign it to a variable of type string. Doing that is wrong, but it won't cause a type error.

  • >
    const n: any = 5;
    const s: string = n;
    s;
    Result:
    5Pass Icon
  • With any, anything can be assigned to anything. We can do things that are complete nonsense, like assign a user object to a variable that's supposed to be an array of numbers.

  • (The next example doesn't cause an error; the user will be in the numbers variable!)

  • >
    const user: any = {name: 'Amir'};
    const numbers: number[] = user;
    numbers;
    Result:
    {name: 'Amir'}Pass Icon
  • We can think of any as temporarily dropping us back into regular JavaScript, where everything is dynamically typed. For that reason, we recommend trying hard to avoid any. (Not because dynamic typing is "bad", but because the whole point of learning and using TypeScript is to get static guarantees!)

  • Although any is undesirable, it still shows up in real-world code. Third-party libraries are one common example.

  • TypeScript code often uses libraries that are written in JavaScript, not TypeScript. In many cases, the library's authors have added high-quality types to the original JavaScript, with little or no use of any. In other cases, there may be a lot of anys in the types. In extreme cases, every function in the library might use any for its parameter and return types, so we hardly get any type guarantees at all.

  • Types with some anys are usually better than having no type definitions at all. If a library truly has no TypeScript type definitions, then we have to write those types ourselves before using the library. (This was common in the past, but is unusual now. Most libraries have TypeScript types, and popular libraries tend to have quite good TypeScript types!) If the library's author has added types with any, that may cost us some safety, but at least we don't have to write types for the library ourselves!

  • When we do use any, how can we limit the danger? One way is to use conditional narrowing to bring the value back into the world of static types. For example, suppose that we use a JavaScript library to query a number from a database. The library's TypeScript type definitions aren't very good, so the number comes back with the type any.

  • We can use a type guard to narrow the type back to number, throwing a runtime error if it's any other type. From that point forward, we can rely on the type system again. It won't let us assign the number to a string variable, for example.

  • (In these examples, you can type error if the code results in a runtime error via throw. You can type type error if it will result in a compile-time type error.)

  • >
    function getNumberFromDatabase(): any {
    return 5;
    }
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    function safeNumber(n: any): number {
    if (typeof n === 'number') {
    return n;
    } else {
    throw new Error('Got a non-number: ' + n);
    }
    }
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    const n: any = 'five';
    const n2: number = safeNumber(n);
    Result:
    Error: Got a non-number: fivePass Icon
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    const n: any = getNumberFromDatabase();
    const n2: number = safeNumber(n);
    n2;
    Result:
    5Pass Icon
  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    const n: any = getNumberFromDatabase();
    const n2: number = safeNumber(n);
    const s: string = n2;
    n2;
    Result:
    type error: Type 'number' is not assignable to type 'string'.Pass Icon
  • Here's a code problem:

    Use any to make the code below compile, even though it's wrong. (When building systems with TypeScript, remember to use any only as a last resort because you don't want this kind of bug in your code!)

    const n: any = 5;
    const s: string = n;
    s;
    Goal:
    5
    Yours:
    5Pass Icon
  • The any type is another example of type unsoundness in TypeScript, an idea that we saw in an earlier lesson. In the case of any, unsoundness is intentional. Creating a variable of type any effectively tells TypeScript not to check the type at all, so all bets are off!