I'm a huge fan of strictNullChecks but it is remarkable how much language features contribute towards making non-nullable types ergonomic. For instance Rust has a lot of primitives on Option a lot nicer.<p>One that I love is `Option::ok_or` (or `Option::ok_or_else` if you like). It takes an Option and converts it to an error. With the try macro (?) it makes Option a lot easier to use. Compare:<p><pre><code> function parseFile(file: File | null) {
if (file === null) {
throw new Error("File must exist");
}
// TS now infers as File
}
</code></pre>
to:<p><pre><code> fn parse_file(file: Option<File>) {
let file = file.ok_or(Error::new("File must exist"))?;
}
</code></pre>
Likewise if you want to apply a function to an Option if it is Some and pass along None otherwise, you can use `Option::map`:<p><pre><code> fn parse_file(file: Option<File>) {
let parse_result = file.map(|f| parse(f));
}
</code></pre>
Indeed it's a little interesting how libraries have adopted paradigms beyond the language. React is extremely expression based, but that makes for a clunky combo with JS' primarily statement based control flow. You see this in React developers' reliance on ternary operators and short circuiting for control flow in JSX.<p>Of course this just JavaScript being a classical imperative language. Not much to do about that.
I was very curious about their “visualization tool”, but it seems to be just one simple script. Which is fine, because it probably did all they wanted. But I believe that there’s great potential for code visualization in many ways!
> In terms of catching errors, we can say that null errors no longer show up in our error dashboard<p>I really wish they tried to have better metrics into if all this actually lowered their defect rates or not. Something a bit more quantitative then them not seeing null errors in their dashboards anymore. At least give us some sense of the measure? How many null error did they see before and what about now? What about other kind of errors? Did they see an uptick elsewhere as a result? What about developer productivity, was that impacted? Etc. This would have been a great opportunity to gather some real data about it.
I'm very curious what they mean by "Figma uses Redux, so we have models, actions and reducers". "Models" is not a term that is normally associated with Redux.<p>Note that we now recommend using the "ducks/slice file" pattern for organizing Redux logic for a given feature in a single file:<p><a href="https://redux.js.org/style-guide/style-guide#structure-files-as-feature-folders-or-ducks" rel="nofollow">https://redux.js.org/style-guide/style-guide#structure-files...</a><p>which you basically get for free anyway if you're using our official Redux Toolkit package and the `createSlice` API (which generates action creators based on your reducers):<p><a href="https://redux.js.org/tutorials/fundamentals/part-8-modern-redux" rel="nofollow">https://redux.js.org/tutorials/fundamentals/part-8-modern-re...</a><p>Obviously the Figma codebase has been around for a while so this isn't an immediate solution to their issue, but it definitely simplifies dealing with most Redux logic.
in addition to counting dependents you can also run the graph through pagerank to find the most impactful files to convert first. This strategy is useful when converting codebases from JS to TS too because it's common to incorrectly type a file when it has a bunch of untyped dependencies, so getting the translation order right saves a lot of rework.
I was always a big fan of Optionals, but having learned Kotlin this year, I was pleasantly surprised at how much non-nullable types seem to remove the need for them. And non-nullable can be just as ergonomic as Optionals with the `?:` operator (or `??` in TypeScript). My only issue when working with `strictNullChecks` in TS is that `null` and `undefined` both exist (thanks JS...). I also wish TS adopted a `Type?` syntax like Kotlin that would signify `Type | null | undefined` and could be used anywhere, not just in function parameters and object types (like TS's current `key?: value` syntax).
This may be slightly off topic, but I'm wondering about this in C++. There is not_null<T *> and some people even argue for using std::reference_wrapper<T> to void null dereference. But isn't the root issue that the compiler allows dereferencing of a pointer that's not guaranteed not null? Wouldn't life be much easier if we'd tweak things so that dereferencing a pointer is not actually allowed unless it's a not_null wrapped one? What are peoples thoughts on this?
Strict null checks have a dramatic positive improvement on code correctness.<p>Just want to point out that Python typecheckers (like mypy) do quite some sophisticated strict null checks when you use the 'Optional' type annotation.
> This website stores data such as cookies to enable necessary site functionality, including analytics, targeting, and personalization. By remaining on this website you indicate your consent.<p>This is illegal.