0

I'm trying to find a more elegant solution for creating a type that allows certain keys of it's index signature to be optional.

This may be a use case for generics, but I can't seem to crack it.

Currently constructing it like this:

//  Required and optional keys allowed as indexes on final type
type RequiredKeys = 'name' | 'age' | 'city'
type OptionalKeys = 'food' | 'drink'

//  Index types use to combine for final type
type WithRequiredSignature = {
    [key in RequiredKeys]: string
}
type WithOptionalSignature = {
    [key in OptionalKeys]?: string
}

//  Build type with required and optional properties on index signature
type FinalType = WithRequiredSignature & WithOptionalSignature

//  Test objects with functional autocomplete
const test1: FinalType = {
    name: 'Test',
    age: '34',
    city: 'New York'
}

const test2: FinalType = {
    name: 'Test',
    age: '34',
    city: 'New York',
    drink: 'Beer'
}

const test3: FinalType = {
    name: 'Test',
    age: '34',
    city: 'New York',
    food: 'Pizza'
}
hebtwo
  • 1
  • 2
    Seems fine to me. you could create a utility type for it but that is not strictly needed and you could use `Record` and `Partial` instead of custom mapped types: https://www.typescriptlang.org/play?#code/PTAEoJQUwRwVwJYCcoBNQEMB26D2AHAFwVywwBtQBrKATwGdNzzcB3NTRhHKADykalQAM24VQhWvigAoSdMixEKVAGk6jALygA5GQC2UHaAA+ujAHMjp3QGMEknXKlRQAeSIky5dQ1DadYVxcVGMzHVQkbionZwVoW1wkVAB1BwALD2JSCgAeABVoeGQOPkIoHEYABSQCKCRJXwAaUHysr3EyitRq2ukG2mbWgDUKOCgAPn9FROSCouU0FvzR8nGpgDJQKowGhDyEpNQC9pzyZdX1iZkZEHAAIURydHlXVgzQFGKVTBxQAmy3lA+D69WIAn+WFA3FQfFA9AQFjIhDgKDirgAYmJyPkXNNDsk0oRMp4zrkFiU1BoWqdvL56C16IQolgLNcgA – Titian Cernicova-Dragomir Feb 15 '22 at 16:01
  • I'm not quite sure what you're asking. I mean, you don't need all those intermediary types and they don't seem to help much vs. [just writing them](https://tsplay.dev/w8JdAm) (or even just [writing the type directly](https://tsplay.dev/NlgKxw)). But I'm guessing you know you can do that, so can you tell us more about what you're trying to do? What the use case is? – T.J. Crowder Feb 15 '22 at 16:02

1 Answers1

1

Your solution is fine if you are getting the keys dynamically. If you arent then why not just do an interface?

interface FinalType {
   name: string;
   age: number;
   city: string;
   food?: string;
   drink?: string;
}
Yftach
  • 712
  • 5
  • 15