3 ms·
> But I will say that in practice it behaves almost exactly like the meaning I described. So you can either take that meaning and run with it and be mostly happ
by ragnese 5y ago
> But I will say that in practice it behaves almost exactly like the meaning I described. So you can either take that meaning and run with it and be mostly happy, or insist on a different meaning that the implementation contradicts at nearly every turn and be upset about it (or you can just not use Record).
What does this even mean? "In practice"? In practice, it behaves exactly as it actually behaves. And it behaves by letting me access ANY string key and ALWAYS giving me something that it claims is a string. Then, I WILL get a runtime error when I write something like `obj['your mom'].length`, but the compiler will let it compile. So, how does it behave as you described? You said it behaves as though there "may" be a string at those keys, but if it did that, it would return a string|undefined. It doesn't. TypeScript is literally incorrect in how it handles this type. You have to either not allow me to assign a regular object to a Record<string, string> OR you have to always return a string|undefined when I do access a Record<string, string> by index.
- brundolf 5y ago> it would return a string|undefined. It doesn't. It does do that, with the `noUncheckedIndexAccess` flag I mentioned. The same is true with arrays: `arr[index]` in reality may or may not return an item (the index may be out of bounds), but by default TypeScript gives it type `el` and not `el|undefined` so that every for-loop in the world doesn't break as soon as TypeScript is added. But it lets you enable this check optionally via the compiler flag. This is a good compromise IMO.
- ragnese 5y agoI mentioned above that I feel like the noUncheckedIndexAccess flag isn't a proper solution either. If I pass a Record<'foo', string>, then the compiler should allow me to get 'foo' out of the object as a string, not a string|undefined. But you're right that arrays have a similar issue. But I feel like the object-like types have more information for the compiler. An Array<T> doesn't have its length as part of the type (but thankfully, TS does have tuple-types, which is neat). A Record does have information about its keys, so we should be able to infer more information about it. I feel like the Record issue is more akin to if TypeScript had an Array<T, N> type, but still let me access the 3 index of an Array<string, 3> and treat it as a string, even though it should be able to figure out that only indexes 0-2 have strings.