top | item 35006420

(no title)

redmorphium | 3 years ago

Interesting. Do these represent oversights in TypeScript's builtin type definitions, or are they artifacts of legacy considerations?

discuss

order

jeroenhd|3 years ago

I think TypeScript's decisions about these methods were done either because early versions of the transpiler couldn't detect certain behaviour or to make the language friendlier to work with.

If you have a function `widgetifyFoo(object: Foo)` and some JSON that you're pretty sure returns a `Foo`, you'd like to be able to do `widgetifyFoo(JSON.parse(data))`. With `any` the method call should just work, but with `unknown` you need to be explicit in what kind of data you're expecting (`widgetifyFoo(JSON.parse(data) as Foo)`). That may be too verbose for some.

The `[1, 2, undefined].filter(x => !!x)` typing is just a limitation of the transpiler. The end result will be an array containing two numbers, but you need to do some complicated validation to get the type right; `filter`s can be very complex if you want them to be, and they do by contract return a (sub)selection of the input. The type guarantee you want as a developer is based on the implementation rather than the underlying type system.

I suspect the `Array.includes` implementation to be a choice by the devs. The check will only succeed if the type matches, so you have a choice between setting the right type on your array (`"matt"|"sofia"|"waqas"|"bryan"` if you want to check for `"bryan"`) or using the type error you receive as an indication your check makes no sense. If you have an immutable array of specifically `["matt","sofia"]`, why even check for `"bryan"`? It won't be there, unless you make a mistake!

Javascript will obviously happily call the method for you and do what you expect, so TypeScript is breaking valid JavaScript standard API code here. That said, I agree with the TypeScript devs that they made the right choice on that one.

Dylan16807|3 years ago

> I suspect the `Array.includes` implementation to be a choice by the devs. The check will only succeed if the type matches, so you have a choice between setting the right type on your array (`"matt"|"sofia"|"waqas"|"bryan"` if you want to check for `"bryan"`) or using the type error you receive as an indication your check makes no sense. If you have an immutable array of specifically `["matt","sofia"]`, why even check for `"bryan"`? It won't be there, unless you make a mistake!

That logic only applies to searching for a constant, and in that case it should go a step further and complain that you're using .includes at all. There's no reason to search for the constant "bryan" or the constant "matt".

The only time it makes sense to use .includes on this array is with a string of [semi-]unknown contents. And yet that's what gets blocked. The typing is wrong.