As an example, when we are doing type check on runtime with Array.isArray(args: any)
args
is any
, first of all it can be unknown
which is nicer.
But why not expect an array in the first place? So:
isArray<T extends unknown[] | readonly unknown[]>(arg: T | unknown): arg is T
So when we use it, we get this results:
const arr = [1, 2] as const // readonly [1, 2]
const arr1 = [1, 2] // number[]
const foo: unknown = null // unknown
if (Array.isArray(arr))
arr // readonly [1, 2]
if (Array.isArray(arr1))
arr1 // number[]
if (Array.isArray(foo))
foo // unknown[] | readonly unknown[]
So if we are checking something that is already a known array, we don't make it unknown[]
While we are also still accepting anything unknown.
Also with this, if we know something is not an array
or unknown
or any
we get type error.
Why is that important?
So let's say we had some unknown
value in a large function and we check if it's an array
.
Then a while later we narrow the type of the value higher in the function, so now we know it's not an array
.
For example we check if it's a string
and if it's a string, then we don't need to check if a string
is an array, because that will always return false.
But now we forget the Array.isArray()
check at the bottom, because TS didn't give any type errors.
This should be same for every type check, not just Array.isArray()
Before making a PR and etc. I wanted to here opinions on this.
And if there is a good reason that this is not being done.