I struggle with Typescript once again. My goal is to create a function for my e2e tests, which goes to a specific page in my app, reloads it and then returns the page-object of the specified page.
However it does not correctly determine the returned value. Right now, Typescript does not like that the createTracksPage()
returns an object with less properties than the createTracksPage()
Furthermore, is there a more elegant way to solve this problem?
Here is a link to the playground
const routes = {
tracks: "tracks",
settings: "settings",
} as const
type IRoutes = keyof typeof routes
async function resetTo<T extends IRoutes>(
location: T,
): Promise<
{
tracks: ReturnType<typeof createTracksPage>
settings: ReturnType<typeof createSettingsPage>
}[T]
> {
// Do side effects..
if (location === "settings") return createSettingsPage()
if (location === "tracks") return createTracksPage()
throw new Error("location is not implemented") // For some reason this does not get treated as "never" code
}
// Create page object functions
function createTracksPage() {
return {
a: "a", b: "b"
}
}
function createSettingsPage() {
return {
a: "a", b: "b" , c: "c" //! Has more properties than tracks return value and TS does not like it
}
}
CodePudding user response:
Would it be good enough to add overloads like this?
async function resetTo(location: "tracks"): Promise<ReturnType<typeof createTracksPage>>
async function resetTo(location: "settings"): Promise<ReturnType<typeof createSettingsPage>>
async function resetTo<T extends IRoutes>(
location: T,
): Promise<
ReturnType<typeof createTracksPage> | ReturnType<typeof createSettingsPage>
> {
...
}
(I'd make it a comment, but the link is too long.)