使用工厂函数生成的 TypeScript 单例会丢失类型
TypeScript singleton generated with a factory function looses typings
我有一个甜蜜的 javascript SDK,其中库在运行时的任何给定点被实例化,但从那时起就是一个单例。如,重复调用文件 return 相同实例的 default
。
我的问题是我在库定义和实例化之间输入的内容丢失了。
查看此代码:
const Factory = (args?: Record<string, unknown>) => {
return {
action: {
method: (code: 'SOME'|'CODES') => console.log('Doing something with', code)
}
}
}
let instance
export default (args?: Record<string, unknown>) => {
if (!instance)
instance = Factory(args)
return instance
}
如果我直接实例化 Factory
,我会得到正确的输入。但是,该文件的导出接口试图确保该实例始终 return 是一个单例。在那个过程中,我们放松了打字。
我应该如何在此处输入 instance
才能保留输入内容?
限制条件:
- 我不想在界面中重新键入与定义大致匹配的所有内容
- 用户可以在运行时的任何时候实例化初始实例(不能假设在 bootstrap 上创建)
- 不应使用 类,因为 returned 的嵌套方法可能很复杂。
您可以使用 ReturnType
实用程序类型来获取 Factory
return 实例的推断类型,然后在 instance
的类型中使用它,并且默认导出的 return 类型。请参阅下面的 LibInstanceType
:
const Factory = (args?: Record<string, unknown>) => {
return {
action: {
method: (code: 'SOME'|'CODES') => console.log('Doing something with', code)
}
}
};
type LibInstanceType = ReturnType<typeof Factory>;
let instance: LibInstanceType | undefined;
export default (args?: Record<string, unknown>): LibInstanceType => {
if (!instance)
instance = Factory(args);
return instance;
};
我有一个甜蜜的 javascript SDK,其中库在运行时的任何给定点被实例化,但从那时起就是一个单例。如,重复调用文件 return 相同实例的 default
。
我的问题是我在库定义和实例化之间输入的内容丢失了。
查看此代码:
const Factory = (args?: Record<string, unknown>) => {
return {
action: {
method: (code: 'SOME'|'CODES') => console.log('Doing something with', code)
}
}
}
let instance
export default (args?: Record<string, unknown>) => {
if (!instance)
instance = Factory(args)
return instance
}
如果我直接实例化 Factory
,我会得到正确的输入。但是,该文件的导出接口试图确保该实例始终 return 是一个单例。在那个过程中,我们放松了打字。
我应该如何在此处输入 instance
才能保留输入内容?
限制条件:
- 我不想在界面中重新键入与定义大致匹配的所有内容
- 用户可以在运行时的任何时候实例化初始实例(不能假设在 bootstrap 上创建)
- 不应使用 类,因为 returned 的嵌套方法可能很复杂。
您可以使用 ReturnType
实用程序类型来获取 Factory
return 实例的推断类型,然后在 instance
的类型中使用它,并且默认导出的 return 类型。请参阅下面的 LibInstanceType
:
const Factory = (args?: Record<string, unknown>) => {
return {
action: {
method: (code: 'SOME'|'CODES') => console.log('Doing something with', code)
}
}
};
type LibInstanceType = ReturnType<typeof Factory>;
let instance: LibInstanceType | undefined;
export default (args?: Record<string, unknown>): LibInstanceType => {
if (!instance)
instance = Factory(args);
return instance;
};