0

I have the following statement in TypeScript:

let foo = {
  bar: []
};

foo.bar.push("Hello World!");

However VSCode keeps complaining that this isn't allowed.

Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345)

So I try to define the type as follows:

let foo = {
  bar: Array<string>
};

But then I get the message that the method push is not allowed:

Property 'push' does not exist on type '{ (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; from(arrayLike: ArrayLike): T[]; from<T, U>(arrayLike: ArrayLike<...>, mapfn: (v: T, k: number) => U, thisArg?:...'.ts(2339)

Only way I found it to work was by defining it as follows:

let arr : Array<string> = [];
let foo = {
  bar: arr
};
foo.bar.push('Hello World!')

Why can't I define the type inside the object itself? It seems cumbersome having to extract the types outside of it, into a variable.

4
  • 3
    You can always just let foo: { bar: Array<string> } = { bar: [] } no need to extract anything out. Just be explicit. Commented Nov 1, 2022 at 9:16
  • 1
    The expression of type '"Hello World!"' can't be used to index type '(...items: never[]) => number' error is because you used square brackets for the push function call Commented Nov 1, 2022 at 9:19
  • foo.bar.push["Hello World!"] is trying to look up the property "Hello World!" on the object foo.bar.push, not call the function foo.bar.push with the argument "Hello World!". Commented Nov 1, 2022 at 9:22
  • @PeteKirkham Darn it, that was a typo whilst rewriting everything to simpler code. I'll edit the question. Commented Nov 1, 2022 at 9:26

2 Answers 2

3

This should work:

let foo = {
  bar: [] as string[]
};

You can also do it in a cleaner (imo) way by using a typed variable:

interface Foo {
    bar: string[];
}

let foo: Foo = { bar: [] }
Sign up to request clarification or add additional context in comments.

Comments

1

You have at least a couple of choices:

You can define the type of foo inline:

let foo: { bar: string[]; } = {
//     ^^^^^^^^^^^^^^^^^^^^
    bar: [],
};

foo.bar.push("Hello World!");

Playground example

You might even extract that out into a reusable type:

type Foo = { bar: string[]; }; // <=== (You could also use `interface`)
let foo: Foo = {
    bar: [],
};

foo.bar.push("Hello World!");

Playground example

Or you can use a type assertion on the blank array as shown by JC97 (in general, type assertions are best avoided, but an assertion on an empty array is a reasonable exception):

let foo = {
    bar: [] as string[],
};

foo.bar.push("Hello World!");

Playground example

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.