You can use function/method overloading for this declaration.
Method
class Foo {
//option 1:
async profilesAll(ids: readonly number[], profileType: ProfileType.Staff): Promise<DatabaseSchema.staffProfiles[]>;
//option 2:
async profilesAll(ids: readonly number[], profileType: ProfileType.Pupil): Promise<DatabaseSchema.pupilProfiles[]>;
//implementation:
async profilesAll(ids: readonly number[], profileType: ProfileType.Staff | ProfileType.Pupil): Promise<(DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles)[]> {
if (profileType === ProfileType.Staff) return getStaff(ids);
return getPupils(ids);
}
}
Note that you need the overloaded signatures first, then and the third implementation signature should be a merge of them. See more on overloading here.
This will then allow you to make type safe calls:
declare const instance: Foo;
//OK:
const pupils = await instance.profilesAll([1, 2, 3], ProfileType.Pupil);
//OK:
const staff = await instance.profilesAll([1, 2, 3], ProfileType.Staff);
//Error - return type is not pupilProfiles:
const wrong: DatabaseSchema.pupilProfiles[] = await instance.profilesAll([1, 2, 3], ProfileType.Staff);
Playground Link
Function
Using functions and overloading them, is analogous but you wouldn't have a class in that case:
//option 1:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Staff): Promise<DatabaseSchema.staffProfiles[]>;
//option 2:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Pupil): Promise<DatabaseSchema.pupilProfiles[]>;
//implementation:
async function profilesAll(ids: readonly number[], profileType: ProfileType.Staff | ProfileType.Pupil): Promise<(DatabaseSchema.staffProfiles | DatabaseSchema.pupilProfiles)[]> {
if (profileType === ProfileType.Staff) return getStaff(ids);
return getPupils(ids);
}
/* ... */
//OK:
const pupils = await profilesAll([1, 2, 3], ProfileType.Pupil);
//OK:
const staff = await profilesAll([1, 2, 3], ProfileType.Staff);
//Error - return type is not pupilProfiles:
const wrong: DatabaseSchema.pupilProfiles[] = await profilesAll([1, 2, 3], ProfileType.Staff);
Playground Link