diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4d43d0348..4138f2af2 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3918,10 +3918,8 @@ export class LuaTransformer { }); } - switch (ownerType.flags) { - case ts.TypeFlags.String: - case ts.TypeFlags.StringLiteral: - return this.transformStringCallExpression(node); + if (tsHelper.isStringType(ownerType, this.checker, this.program)) { + return this.transformStringCallExpression(node); } // if ownerType is a array, use only supported functions diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 0d8276aa9..13ff34e5a 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -140,6 +140,14 @@ export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts } } + if (type.isUnion()) { + return type.types.every(t => isStringType(t, checker, program)); + } + + if (type.isIntersection()) { + return type.types.some(t => isStringType(t, checker, program)); + } + return ( (type.flags & ts.TypeFlags.String) !== 0 || (type.flags & ts.TypeFlags.StringLike) !== 0 || diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 3d6fc3c9f..8768818cf 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -349,6 +349,22 @@ test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`fo } ); +test("scoped string-union inference", () => { + const inp = "foo"; + + const result = util.transpileAndExecute(` + const union: string = "${inp}"; + + if (union === "foo" || union === "bar") { + return union.length; + } + + return 0; + `); + + expect(result).toBe(inp.length); +}); + test.each([ "function generic(string: T)", "type StringType = string; function generic(string: T)",