3

Assume I have the following:

export const ContentType = {
    Json: "application/json",
    Urlencoded: "application/x-www-form-urlencoded",
    Multipart: "multipart/form-data",
};

export interface RequestOptions {
    contentType: string,
}

const defaultOptions: Partial<RequestOptions> = {
    contentType: ContentType.Json,
};

How would I go about restricting contentType so that only keys declared in ContentType are used?

2
  • Don't you want to limit contentType to the values of ContentType, not the keys? Commented Apr 14, 2017 at 21:30
  • Looks like you might be able to use Lookup types like in this answer... Commented Apr 14, 2017 at 21:36

2 Answers 2

11

This is my preferred way as of TypeScript 2.1:

export const contentTypes = {
    "application/json": true,
    "application/x-www-form-urlencoded": true,
    "multipart/form-data": true
};

type ContentType = keyof typeof contentTypes;

export interface RequestOptions {
    contentType: ContentType;
}

const defaultOptions: Partial<RequestOptions> = {
    contentType: "application/json",
};

Try it in TypeScript Playground

  • Define a set of valid strings in an object literal.
  • Create a type that contains the keys of that object, using keyof. It's a string union type.
  • Type your string property to that union type, and the compiler will only allow those strings.
Sign up to request clarification or add additional context in comments.

1 Comment

Can't believe I stumbled upon the famous Robert Penner in the wild! Just wanted to say I'm a huge fan.
1

You can use string literal types. Instead of typing contentType as string, type it as a literal type of possible values.

export interface RequestOptions {
    contentType: "application/json" | "multipart/form-data" | "multipart/form-data:"
}

To avoid repeating your constants you can declare them separately and type contentType as typeof ConstantString:

export const ContentTypeJson = "application/json";
export const ContentTypeUrlencoded = "application/x-www-form-urlencoded";
export const ContentTypeMultipart = "multipart/form-data";


export interface RequestOptions {
    contentType: typeof ContentTypeJson| typeof ContentTypeUrlencoded | typeof ContentTypeMultipart,
}

const defaultOptions: Partial<RequestOptions> = {
    contentType: ContentTypeJson,
};

2 Comments

Issue I have with this is that I'm just repeating the value everywhere. While I get enforcement that only valid values are used, I'm still repeating them.
@Omega I have updated the answer with another approach where you don't have to repeat constants.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.