skip to Main Content

Why is Typescript not detecting that I’ve checked only part of unknown type, and not it’s nested properties thus resulting in runtime error?

interface User {
    name: string,
    age: number
}

const externalData: unknown = [1, 2, 3];

(Array.isArray(externalData) ? externalData : [])
    .reduce<User[]>((acc, curr) => {
        return [
            ...acc,
            {
                name: curr.some.nested.property, // not detecting that these properties may not exist on type 'any'
                age: curr.some.nested.another.propety // not detecting that these properties may not exist on type 'any'
            }
        ]
    }, []);

2

Answers


  1. noImplicit will yell at you when there are no typings.
    For example function (foo) { ... }, foo has no type so it’s implicitly any.

    In your case (Array.isArray(externalData) ? externalData : []) is inferred to any.

    because the empty array is any[].

    Login or Signup to reply.
  2. It looks like TypeScript is narrowing your unknown externalData to any[] when Array.isArray(externalData) is true. (I would have expected unknown[].) Here are a couple of simpler tests:

    const d: unknown = ["something"];
    const a = Array.isArray(d) ? d : null;
    //    ^? const a: any[] | null
    

    Notice how it’s clearly the true part of the conditional that’s contributing the any[] type to the union.

    Just going by the documentation (I don’t have a deep history in this part of TypeScript, or really any part), that would seem to be a case that should be caught:

    In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type…Turning on noImplicitAny however TypeScript will issue an error whenever it would have inferred any

    I don’t see any issue for this in the issue list, although there are several outstanding issues with the result of narrowing array types (such as this one where ReadonlyArray<T> is narrowed to any[]).

    Above my pay grade whether it’s a bug or limitation, but it’s that narrowing that appears to be what isn’t getting caught.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search