DEV Community

Cover image for Advanced TypeScript Exercises - Answer 8
Pragmatic Maciej
Pragmatic Maciej

Posted on

6 2

Advanced TypeScript Exercises - Answer 8

The question was about creating indexed type assignable to string. For the full question please visit Advanced TypeScript Exercises - Question 8

The Answer

const concatToField =
  <T extends Record<K, string>
  , K extends keyof T >(obj: T, key: K, payload: string): T => {
    const prop = obj[key];
    return { ...obj, [key]: prop.concat(payload) }; // works đź‘Ť
}
Enter fullscreen mode Exit fullscreen mode

The key to the problem was obj[key] which is a type of T[K] so the whole problem comes to - how to ensure T[K] is always string. Trying to narrow the K type only for string values in T will not work, as T can have no string fields at all, so we can end by never(the bottom type).

The simplest solution is restricting T to be extending Record<K, string>, what does it mean - we say that our T needs to have key K being a string. Now if we put key which will be having different value than string there will be compilation error.

Full solution available in the playground

This series will continue. If you want to know about new exciting questions from advanced TypeScript please follow me on dev.to and twitter.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (2)

Collapse
 
drazbest profile image
dr-azbest •

I challanged myself and in my version you can pass object with number properties but you can only edit string type ones:

type GetStringTypeKeys<FieldsObj> = {[P in keyof FieldsObj]: FieldsObj[P] extends string ? P : never}[keyof FieldsObj];

const concatToField =
  <T extends {[R in GetStringTypeKeys<T>]: string}, K extends GetStringTypeKeys<T>>(obj: T, key: K, payload: string): T => {
    const prop = obj[key]; // compile error
    return { ...obj, [key]: prop.concat(payload) }; // compile error
}
Enter fullscreen mode Exit fullscreen mode

Playground Link

Collapse
 
nmonastyrskyi profile image
Nikita Monastyrskiy •

Wow, nice! For some reason, I didn't realize that we can use "K" in "T" before we actually "declared" "K"

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

Best practices for optimal infrastructure performance with Magento

Running a Magento store? Struggling with performance bottlenecks? Join us and get actionable insights and real-world strategies to keep your store fast and reliable.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️