0

I am trying write a function that can take an array or an object but running into these conflicts. How do I tell TS specifically not to look for length if something is an object or a property foo if its an array?

interface Stuff {
  list: [] | Obj;
}
interface Obj {
    foo: "bar"
}
function generateSomething(data:Stuff) {
    console.log(data.list.length) // Property 'length' does not exist on type 'Obj'
    console.log(data.list.foo) // Property 'foo' does not exist on type '[]'
}
5
  • you can use that variable type is array or string or object with typeof VARIABLE Commented Apr 10, 2021 at 15:31
  • You can't use your data variable until you're 100% certain it's either an array or an object, because otherwise Typescript can't guarantee type saftey. Commented Apr 10, 2021 at 15:32
  • You could use Array.isArray( data.list ) in an if statement to distinguish between the two. Commented Apr 10, 2021 at 15:32
  • you can use if (Array.isArray(data.list)) then check length Commented Apr 10, 2021 at 15:33
  • Side note: the type [] is specifically the empty tuple type; an array which definitely has length 0. Presumably in practice you'd want something more useful like string[] (a synonym for Array<string>). Commented Apr 10, 2021 at 17:38

1 Answer 1

2

You just need to help Typescript understand at runtime which it is.

function generateSomething(data:Stuff) {
    // if ("length" in data.list)
    // if (data.list instanceof Array)
    if (!("foo" in data.list)) {
        console.log(data.list.length);
    } else {
        console.log(data.list.foo);
    }
}

typescript playground

As Ganesh pointed out in the comments, Array.isArray(data.list) works too.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.