看起来你正在使用 T extends 'CREATE' | 'UPDATE'
扩展一个字符串,我不确定你是否可以这样做。这基本上是在说“它可以是任何字符串或这两个特定的字符串” - 这本质上与说“任何字符串”相同。
如果你想表达的是你只希望输入值为 'CREATE'
或 'UPDATE'
,那么你只能通过以下方式允许这两个字符串:CreateModel(mode: 'CREATE' | 'UPDATE')
另一个问题是你正在使用 this
,但你处于一个函数内部,而不是一个类中,所以它的工作方式并不完全相同,你可能会遇到一些问题。通常情况下,这是不被鼓励的,你应该使用一个类。
这是我想到的,它可以编译。我知道它有点偏离了你最初的问题,但我认为这也是因为你没有在这里使用类。
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');
这是一个关于如何将其作为类实现的想法(也可以参考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);