TS-Record, XPath test, update Redux state, proxy pattern

Cover Image for TS-Record, XPath test, update Redux state, proxy pattern

In this blog post, I will be sharing a few tips and tricks that I have recently learned about TypeScript, XPath testing, updating Redux state, and the proxy pattern in JavaScript. These are all topics that I have found to be incredibly useful in my work and I hope that you will find them to be helpful as well. Let's dive in!

Records in TypeScript

Using records in TypeScript can improve the readability of your types.

// do
type asdfT = Record<string, string>

// don't
type asdfT = {[k: string]: string}

// -----
// usage 
const asdf: asdfT  = {  a: "value1",  b: "value2"}

Records are available since TypeScript 2.1 and you can read more about them in the TS Doc on Record Type.

The TS-Record type maps keys of the first type to values of the second type, so remember they work a bit different than “Records” in some other programming languages.

XPath testing in the Browser

In most modern browsers you can test XPath queries directly in the devtools. That means you can query the content of the website you have currently opened. XPath can often be handy e.g. for writing selectors in automated tests, when otherwise you don’t get some hard to query elements (for example with a CSS-Selector).

In Chrome querying XPath from the browser is as simple as $x(XpathQuery) . So let’s say you want to get all div elements, here you go: $x(&quot;//div&quot;).

Finding out about it has already saved me a lot of time.

Update Redux state

This tip is a bit specific and mostly makes sense if you:

  • use redux for state management
  • fetch inside your redux slices

I would not even recommend this setup today (since, e.g., RTK Query seems to be the better way to do it). But if you somehow end up assigning objects with many properties to your Drafts (could also be using useImmer), here is a nice simplification:

// do
Object.assign(state, structuredClone(action.payload));

// don't
state.cat = action.payload.cat;
state.dog = action.payload.dog;
...

The structuredClone function is available in modern browsers and latest Node.js versions, but you can also easily polyfill it if you need to support older runtimes. Be aware that in the example above, values with undefined in the action payload don’t overwrite values in the state. You have to add that behavior if you need it.

The proxy pattern

I recently learned about the proxy pattern in JavaScript, which is a design pattern used to control access to an object. You can use it to add additional behavior or restrictions to an object, without modifying its original code. I ended up doing the same thing (without the Proxy class) a few times, so I think it has relevant use cases, but they are rather seldom.

The first example I can remember is, when you build your own abstraction over a browser storage layer (Cookie, Local Storage, Session Storage, …). You will often want to have get/set like methods and maybe some validations, which seems like a perfect match for using the proxy pattern.

I first learned about the proxy pattern in JavaScript from an article on patterns.dev, which provided a clear and concise explanation of the pattern and its uses.

Updates

  • New Viewport units: You can now use viewport units that respect the largest or smallest size of the viewport display in order to take rounded corners or a notch into account. Read more about it here https://web.dev/viewport-units/.
  • Also new is the TypeScript satisfies keyword, that can make sure an object satisfies the constraints of a type while keeping the narrow type of the specific values assigned to properties. It can also be combined with the const keyword if you want to keep the most specific type of a value. Read more about it in the Release Notes of TypeScript 4.9.

That's all for this post. As always, thank you for reading 🙏, and I highly appreciate your feedback.