Bug Report
π Search Terms
code path, type narrowing
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about type narrowing
β― Playground Link
TypeScript Nightly
TypeScript v4.5.4
TypeScript v3.3.3 (no private fields)
π» Code
type GenericClass = new (...args: any) => any;
export default class SingletonFactory<T extends GenericClass> {
readonly #instanceClass: T;
#instance?: InstanceType<T>;
constructor(instanceClass: T) {
this.#instanceClass = instanceClass;
}
getInstance(options?: ConstructorParameters<T>): InstanceType<T> {
if (this.#instance === undefined) {
if (!options) {
// Error if both instance and options are undefined
throw new Error('No instance found, and no options provided');
}
// Create new instance if not defined, and options are provided
this.#instance = new this.#instanceClass(options);
return this.#instance; // Error: Type 'InstanceType<T> | undefined' is not assignable to type 'InstanceType<T>'.
}
return this.#instance;
}
}
π Actual behavior
After creating a new instance of this.#instanceClass, TypeScript still reports the type as possibly undefined.
π Expected behavior
After creating a new instance and assigning it to this.#instance, the type of this.#instance should narrow to only InstanceType<T>. A workaround can be achieved by assigning the new instance to an intermediary variable, and then returning the intermediary variable instead.
Example playground of workaround
Additionally, even though the type of the property is InstanceType<T> | undefined, other similar situations properly narrow the code path. I've created an example using string | undefined here for comparison.
Thanks!
Bug Report
π Search Terms
code path, type narrowing
π Version & Regression Information
β― Playground Link
TypeScript Nightly
TypeScript v4.5.4
TypeScript v3.3.3 (no private fields)
π» Code
π Actual behavior
After creating a new instance of
this.#instanceClass, TypeScript still reports the type as possibly undefined.π Expected behavior
After creating a new instance and assigning it to
this.#instance, the type ofthis.#instanceshould narrow to onlyInstanceType<T>. A workaround can be achieved by assigning the new instance to an intermediary variable, and then returning the intermediary variable instead.Example playground of workaround
Additionally, even though the type of the property is
InstanceType<T> | undefined, other similar situations properly narrow the code path. I've created an example usingstring | undefinedhere for comparison.Thanks!