So it looks like you are extending a string with T extends 'CREATE' | 'UPDATE', I'm not sure you can do that. This is basically saying "it can be any string or these two specific strings" - and this is essentially the same as saying "any string"
If you are trying to say you only want the input value to be either 'CREATE' or 'UPDATE' then you can only allow those two strings by doing
CreateModel(mode: 'CREATE' | 'UPDATE')
Another issue is that you are using this but you are inside of a function, not a class, so it doesn't work quite the same way and you might have some issues regardless. generally this is discouraged and you should use a class.
Here's what I came up with, and it compiles. I know it kinda goes "around" what your original question was in the first place, but I believe that's also because you aren't using a class here
type ICreateType = { name: string };
type IUpdateType = { name: string; email: string | undefined };
interface IReturnCreateValue {
value: ICreateType,
};
interface IReturnUpdateValue {
value: IUpdateType,
onChange: (change: Partial<IUpdateType>) => void;
};
export function CreateModel(mode: 'CREATE' | 'UPDATE'): IReturnCreateValue | IReturnUpdateValue {
if (mode === 'CREATE') {
return { value: { name: '' } };
}
let value: IUpdateType = { name: '', email: '' };
return {
value: value,
onChange(change: Partial<IUpdateType>) {
value.email = change.email;
}
};
};
CreateModel('CREATE');
CreateModel('UPDATE');
CreateModel('foo'); //compile error
Here's an idea of how this might work as a class (also on typescript playground )
type IValueType = { name: string; email?: string };
interface IValue {
value: IValueType,
onChange?: (change: Partial<IValueType>) => void;
};
class CreateModel {
value: IValueType = { name: '' };
onChange: undefined | ((c: Partial<IValueType>) => void) = undefined;
constructor(private readonly shouldUpdate: boolean) {
if (this.shouldUpdate) {
this.onChange = (change: Partial<IValueType>) {
this.value.email = change.email;
}
}
}
}
const a = new CreateModel(false);
const b = new CreateModel(true);