Chris Drackett
Chris Drackett

Reputation: 1327

Can I create a type based on characters within a string

I have a function that takes a 2 character string and expands it to a full property. For example it'll take mr and return MarginRight or pt and return PaddingTop.

My question here is how would one go about typing such a function? basically I want to limit the first character of the input string to m or p and the second character to r, l, t, or b. So far I just have ([marginOrPadding, direction]: string): string but that obviously will accept a lot more than I want.

Upvotes: 0

Views: 93

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

Since this a finite and relatively low number of items you can use overloads, or you can use an interface to map the input strings to the output type and use that in your function signature:

interface Abbreviations {
    "mr" : "MarginRight"
    "pr" : "PaddingRight"
    // and the rest 
}
function expand<K extends keyof Abbreviations>(k: K): Abbreviations[K] {
    return null!;
}

expand("mr") // retruns MarginRight
expand("SS") // error

You could use also keep the abbreviations in an object and use the type of that instead, if yo don't already have an implementation:

function withLiterals<
    T extends Record<string, V>, 
    V extends string | boolean | number | symbol | null | undefined | Record<string, V>
>(input: T ): T { return input }
const abbreviations = withLiterals({
    "mr" : "MarginRight",
    "pr" : "PaddingRight"
    // and the rest 
})
function expand<K extends keyof typeof abbreviations>(k: K): typeof abbreviations[K] {
    return null!;
}

expand("mr") // retruns MarginRight
expand("SS") // error

Upvotes: 2

Related Questions