Why does Typescript assume string[]? And what is the correct way of
creating an array of numbers here?
Because object property names are always strings (or, to properly explain that, are always coerced to strings), hence the default signature assumes a string[]
as default type, as the intellisense even suggests:

Besides, you can't ensure that, at runtime, those keys will be numbers. Defining a type that strictly defines that object to have numeric keys has no effect at runtime, hence it's always safer to safely cast the values to the desired type:
const sizes: number[] = Object.keys(foo).map(Number); // beware of possible NaN here.