Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to restrict a type when defining, but have the real object type by just the restricted version?

Given:

interface Customer {
  name: string
  address: string
  phone: string
}

type PartialRecord<K extends keyof any, T> = {
    [P in K]?: T
}

// For this, I want the keys to be only fields that are in customer, but I need the derived type to be the fields  
// that are actually defined here - not the full set of those in customer
const editableFields: PartialRecord<keyof Customer, string> = {
    name: 'The customer name',
} as const;

type EditableCustomer = Pick<Customer, keyof typeof editableFields>

// This gives an error - missing address and phone
const x: EditableCustomer = {
    name: 'Bob'
}

The idea is I want to have a function foo(c: EdiableCustomer) that has access just to the fields that are actually editable, based on what labels are defined in editableFields, but I want to maintain the type restriction in the definition of editableFields to only be the keys of Customer, but still have the resulting type be just the union of what is actually defined, and not the entirety of Customer.

The real usage is a bit more complicated than this, but this is my best shot at distilling the problem down into a minimal case. I feel like there is a template solution to this to define editableFields as some type that is inheritable from the PartialRecord, but my template-fu is not great in TS.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Any ideas?

>Solution :

Seems like a perfect case for the satisfies operator:

const editableFields = {
    name: 'The customer name',
} satisfies PartialRecord<keyof Customer, string>;

The satisfies keyword tells typescript that it should infer editableFields‘s type based on the actual values written (in this case, that type is { name: string; }), but if the resulting type isn’t compatible with PartialRecord<keyof Customer, string>; you want an error to be shown.

Playground link

Documentation of Satisfies

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading