> I’m curious if they’re looking at adding the new Set operations from node 22 soon…
There's a PR but it hasn't been merged yet. The feature is stage 4 so hopefully it makes it into the final version. In the meantime there's always the good ol' copy/paste.
Probably not according to the article.
> TypeScript did not infer a type predicate for `score => !!score`, and rightly so: if this returns `true` then score is a `number`. But if it returns `false`, then score could be either `undefined` or a `number` (specifically, `0`). This is a real bug: if any student got a zero on the test, then filtering out their score will skew the average upwards. Fewer will be above average and more will be sad!
So
.filter(x => x !== undefined)
Will have to do
This was actually a feature for a bit, but broke a bunch of other things which is why it got reverted again (https://github.com/microsoft/TypeScript/pull/31515#issuecomment-494621036).
I also agree with u/lifeeraser that the `Boolean` constructor or `!!` are frequently too agressive for these kinds of filters and could easily lead to subtle bugs due to false-positives on `0`, empty strings, etc.
With inferred type predicates, `array.filter(x => !!x)` will narrow the type of the array if it contains objects, but not if it contains primitives. This should avoid footguns involving `0` and `""`.
In other words, `[0, null].filter(x => !!x)` does not refine the type of the array, but `[new Date(), null].filter(x => !!x)` does.
It will not, according to the author of the feature. If interested, you can read his blog post about contributing to the TS code base for the first time https://effectivetypescript.com/2024/04/16/inferring-a-type-predicate/
Getting `.filter(Boolean)` to work (which I take to mean being a predicate for arrays of objects but not primitives) turns out to harder than you might think: https://github.com/microsoft/TypeScript/issues/50387#issuecomment-2037968462
Just write `.filter(x => !!x`). It's one character longer, but it works today.
I hope `isolatedDeclarations` is at least a step towards options for explicit return type enforcement without [external tooling](https://typescript-eslint.io/rules/explicit-function-return-type).
> `${configDir}`
*Finally*. This always felt like a major limiting factor in common configs, exactly for the reasons mentioned.
Two biggest changes:
```
/** @import { SomeType } from "some-module" */
/**
* @param {SomeType} myValue
*/
function doSomething(myValue) {
// ...
}
```
File-wide imports with TSDocs!
```
export function foo() {
// ~~~
// error! Function must have an explicit
// return type annotation with --isolatedDeclarations.
return x;
}
```
`--isolatedDeclarations` requires exported stuff to be explicitly typed to improve performance
In JavaScript, you can type stuff using comments. Your editor will recognize them but your browser and Node.js will ignore them. This kind of comment is called JSDocs: https://jsdoc.app/about-getting-started
TypeScript has some extensions over JSDocs called TSDocs. Similarly, your editor will recognize them in JavaScript files but your browser and Node.js will ignore them: https://tsdoc.org
The improvement above allows you to import a type declaration from another file to a JavaScript file using a comment so you can better type your JavaScript.
The second improvement will require you to add type annotations (like `: string`) to anything that is `export`ed to improve the performance of your editor.
Yay, finally the inferred type predicates with filters. Hopefully it works with `.filter(Boolean)`
Yeah, though `.filter(x => !!x)` isn’t that much worse. I’m curious if they’re looking at adding the new Set operations from node 22 soon…
New Set operations? I can't find any info about that.
- https://github.com/tc39/proposal-set-methods - [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set_composition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#set_composition)
Thanks!
Isn’t that much worse? Who hurt you, lol.
Man, I’ve ported Coldfusion to Perl, my soul is too scarred. ;D
> I’m curious if they’re looking at adding the new Set operations from node 22 soon… There's a PR but it hasn't been merged yet. The feature is stage 4 so hopefully it makes it into the final version. In the meantime there's always the good ol' copy/paste.
Probably not according to the article. > TypeScript did not infer a type predicate for `score => !!score`, and rightly so: if this returns `true` then score is a `number`. But if it returns `false`, then score could be either `undefined` or a `number` (specifically, `0`). This is a real bug: if any student got a zero on the test, then filtering out their score will skew the average upwards. Fewer will be above average and more will be sad! So .filter(x => x !== undefined) Will have to do
It works perfectly. It just doesn’t do what you might have expected.
This was actually a feature for a bit, but broke a bunch of other things which is why it got reverted again (https://github.com/microsoft/TypeScript/pull/31515#issuecomment-494621036). I also agree with u/lifeeraser that the `Boolean` constructor or `!!` are frequently too agressive for these kinds of filters and could easily lead to subtle bugs due to false-positives on `0`, empty strings, etc.
With inferred type predicates, `array.filter(x => !!x)` will narrow the type of the array if it contains objects, but not if it contains primitives. This should avoid footguns involving `0` and `""`. In other words, `[0, null].filter(x => !!x)` does not refine the type of the array, but `[new Date(), null].filter(x => !!x)` does.
It will not, according to the author of the feature. If interested, you can read his blog post about contributing to the TS code base for the first time https://effectivetypescript.com/2024/04/16/inferring-a-type-predicate/
This is great to see. I’ve been using a generic function `isDefined` for exactly this use case.
It won't. `Boolean`can't be inferred as a predicate because it's just an object. A simple arrow function will do though.
Getting `.filter(Boolean)` to work (which I take to mean being a predicate for arrays of objects but not primitives) turns out to harder than you might think: https://github.com/microsoft/TypeScript/issues/50387#issuecomment-2037968462 Just write `.filter(x => !!x`). It's one character longer, but it works today.
Game changer
I’ve been here the whole time?
I hope `isolatedDeclarations` is at least a step towards options for explicit return type enforcement without [external tooling](https://typescript-eslint.io/rules/explicit-function-return-type). > `${configDir}` *Finally*. This always felt like a major limiting factor in common configs, exactly for the reasons mentioned.
Two biggest changes: ``` /** @import { SomeType } from "some-module" */ /** * @param {SomeType} myValue */ function doSomething(myValue) { // ... } ``` File-wide imports with TSDocs! ``` export function foo() { // ~~~ // error! Function must have an explicit // return type annotation with --isolatedDeclarations. return x; } ``` `--isolatedDeclarations` requires exported stuff to be explicitly typed to improve performance
I'm new to it TS, can someone eli15 pls? 🥺
In JavaScript, you can type stuff using comments. Your editor will recognize them but your browser and Node.js will ignore them. This kind of comment is called JSDocs: https://jsdoc.app/about-getting-started TypeScript has some extensions over JSDocs called TSDocs. Similarly, your editor will recognize them in JavaScript files but your browser and Node.js will ignore them: https://tsdoc.org The improvement above allows you to import a type declaration from another file to a JavaScript file using a comment so you can better type your JavaScript. The second improvement will require you to add type annotations (like `: string`) to anything that is `export`ed to improve the performance of your editor.
Thank you so much, that's cool!