I am having certain types that are categorized based on mimetypes
export type MimeType = 'image' | 'application' | 'text';
export type ApplicationMimeType = '.pdf' | '.zip';
export type ImageMimeType = '.gif' | '.png' | '.jpeg' | '.jpg' | '.svg' ;
export type TextType = '.csv' | '.txt';
export type ExtensionTypes = ImageMimeType[] | ApplicationMimeType[] | TextType[];
export type FileType = {
image?: ImageMimeType[];
application? : ApplicationMimeType[];
text? : TextType[]
};
Now when I use it in a function, then use Object.entries when a certain object is passed, the key type is set to string. Is there a way for this key to be set to the type of MimeType?
I tried the solution that is given in this link: Typescript Key-Value relation preserving Object.entries type
Code I tried that is giving me error Type 'undefined' is not assignable to type 'string[]'
.
How can I restrict key to be MimeType
and extensions to be ExtensionTypes
export type Entries<T> = {
[K in keyof T]: [extensions: T[K]][];
}[keyof T][];
export const getAcceptedFileTypes = (mimeTypes: FileType) => {
const acceptedTypes = {};
Object.entries(mimeTypes as Entries<mimeTypes>).forEach(([key, extensions]) => {
if (key === 'text') {
acceptedTypes['text/*'] = extensions;
} else if (key === 'image') {
extensions.forEach(
(image) => (acceptedTypes[`image/${image.substring(1)}`] = [image])
);
} else {
extensions.forEach(
(application) =>
(acceptedTypes[`application/${application.substring(1)}`] = [
application,
])
);
}
});
return acceptedTypes;
};
getAcceptedFileTypes({ image: ['.png'], application: [] })
tsconfig
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
},
{
"path": "./.storybook/tsconfig.json"
}
]
}
3
Answers
You can use TypeScript’s Declaration Merging to add an overload to
Object.entries
like thisTS Playground
TL;DR
You can define your
Entries
like this:and you’ll notice that
Entries<FileType>
also includesundefined
that’s because the way
FileType
is definedwhat you probably need is an union type like this:
As an alternative to the solution provided by @Teneff, instead of extending the entries type, you should first redeclare the
Entries
with the following:Also, you should change the way you do the type assertion as follows.
playground
Check in Typescript Playground