Additional safety with typescript
Aleksei Mohnatkin
Senior Frontend Engineer | React/Typescript developer | Frontend Architect
Recently discovered cool typescript feature: noUncheckedIndexedAccess compiler option
It helps to avoid runtime errors in many cases.
type User = { name: string; age: number };
const users: User[] = [
{ name: "John", age: 23 },
{ name: "Bob", age: 60 },
];
const firstFilteredUserName = users.filter(({ age }) => age > 100)[0].name;
Here filter returns an empty array and you'll catch the bug only after running the code or even on production in some edge cases
Another example:
const usersMap: Record<string, User> = {
id1: { name: "John", age: 23 },
id2: { name: "Bob", age: 60 },
};
const username = usersMap.id3.name;
This also doesn't throw compile error because usersMap key has type string
Enabling noUncheckedIndexedAccess will save you from unexpected bugs, in examples above typescript will tell you that object can be undefined and you need to do additional check.
Looks awesome, however in some cases it behaves weird.
String.split returns string[] which means that it might be an empty array, but in fact, that's not true. First element element is always a string, it can be empty empty string but not undefined. So the standard type definition is not correct.
Thanks to declaration files, we can fix it. First we define NonEmptyArray type
type NonEmptyArray<T> = [T, ...T[]]
Than in .d.ts file define overload for split method
declare interface String {
split(separator: string | RegExp, limit?: number | undefined): NonEmptyArray<string>;
}
Works like a charm.
Did you face similar issues with standard type definitions?
Senior Software Engineer, Video Player, Web and Connected devices
5 个月Thank you for your article Aleksei Mohnatkin! I’d like to disagree with you. Although I agree that this tsconfig option has advantages for all the cases mentioned above, it doesn’t allow engineers using basic for(;;) loops - any value by index will be optional so you have to use type assertions (which is mostly anti-pattern), disable type error with ts-expect-error comment (which may hide other issues) or add more boilerplate (potentially analogue of forEach) which kills the benefit of for(;;) loops - the performance. For me and the projects where I worked last 4 years, this is a concern and the immediate blocker, therefore cancelling all other feature’s benefits. TS issue - https://github.com/microsoft/TypeScript/issues/53678 TS playground - https://www.typescriptlang.org/play/?noUncheckedIndexedAccess=true#code/CYUwxgNghgTiAEYD2A7AzgF3rGUCeAXPCgK4C2ARiDANoC6A3AFBMQhZrnwC88ADMwBmSGPAAUbLAEse-BvBkAebDFx4AdGxQBzDAAt5UgNRGAlPADeTePEnwAblAgkEvHPhpTG1+AHpfNgB6APw+nGTwRryOziDMAL5AA
Tech Entrepreneur | Team Lead & Software Engineer | Author & Speaker | Follow for daily posts about Mindset, Personal Growth, and Leadership
5 个月Wow ??
Senior Frontend Developer, 7+ years of experience, React, Typescript, Redux/Zustand
5 个月Thank you! Very informative!!
Lead Software Engineer, People Manager
5 个月Interesting feature, something to consider when new project starts. However on large and old ones would bring too much headache to add extra non types imho
Senior Frontend Developer 6+YoE. React | Next.js |Typescript | Redux
5 个月I’ll take note of that, thanks!