I have this interface:
export interface IScene<R extends string> {
path: R;
params?: SceneParams;
}
SceneParams interface:
export interface SceneParams {
[key: string]: string;
}
This works totally fine when I create a scene like:
interface PostDetailScene extends IScene<PostRoute.Detail> {
params: PostDetailSceneParams;
}
PostDetailSceneParams:
export interface PostDetailSceneParams extends SceneParams {
postId: string;
}
All these code gets correct type checking:
// CORRECT
getPathWithParams({
path: PostRoute.Detail,
params: { postId: '4' },
});
getPathWithParams({
path: UserRoute.List,
});
getPathWithParams({
path: UserRoute.List,
params: undefined,
});
// ERROR
getPathWithParams({
path: PostRoute.Detail,
params: undefined,
});
getPathWithParams({
path: PostRoute.Detail,
});
getPathWithParams({
path: UserRoute.List,
params: { wrongParam: 'value' },
});
Now I have a scene where I don't want to pass any props. This scene is the UserListScene:
interface UserListScene extends IScene<UserRoute.List> {
params?: never;
}
You see I have to explicitly type params?: never (or params?: undefined - I also don't know which type I should use here because here the params would/should really never get passed - but with never the compiler gets also satisfied with undefined so I don't see that much difference)
My question is: Is there a solution for changing the IScene interface so that I don't have to type params?: never or params?: undefined when there are no params for this scene?
I just want to write:
interface UserListScene extends IScene<UserRoute.List> {}
or:
type UserListScene = IScene<UserRoute.List>;
EDIT:
This function should also get correct type checking:
export function getPathWithParams(scene: Scene): string {
if (!scene.params) {
return scene.path;
}
let pathWithParams: string = scene.path;
const paramsAsString = Object.keys(scene.params);
paramsAsString.forEach((param: string) => {
pathWithParams = pathWithParams.replace(`:${param}`, scene.params[param]);
});
return pathWithParams;
}