diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 5a30fbb88..e497f6b87 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2990,23 +2990,16 @@ export class LuaTransformer { // Check for primitive types to override const type = this.checker.getTypeAtLocation(node.expression); - switch (type.flags) { - case ts.TypeFlags.String: - case ts.TypeFlags.StringLiteral: - return this.transformStringProperty(node); - case ts.TypeFlags.Object: - if (tsHelper.isExplicitArrayType(type, this.checker)) - { - return this.transformArrayProperty(node); - } - else if (tsHelper.isArrayType(type, this.checker) - && tsHelper.isDefaultArrayPropertyName(node.name.escapedText as string)) - { - return this.transformArrayProperty(node); - } - } + if (tsHelper.isStringType(type)) { + return this.transformStringProperty(node); - if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) { + } else if (tsHelper.isArrayType(type, this.checker)) { + const arrayPropertyAccess = this.transformArrayProperty(node); + if (arrayPropertyAccess) { + return arrayPropertyAccess; + } + + } else if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) { return this.transformConstEnumValue(type, property, node); } @@ -3088,13 +3081,13 @@ export class LuaTransformer { } // Transpile access of array properties, only supported properties are allowed - public transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { + public transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { switch (node.name.escapedText) { case "length": return tstl.createUnaryExpression( this.transformExpression(node.expression), tstl.SyntaxKind.LengthOperator, node); default: - throw TSTLErrors.UnsupportedProperty("array", node.name.escapedText as string, node); + return undefined; } } diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index c723b5b24..eecdf4cd1 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -21,6 +21,16 @@ export class ArrayTests { Expect(result).toBe(5); } + @Test("Array union length") + public arrayUnionLength(): void { + const result = util.transpileAndExecute( + `function makeArray(): number[] | string[] { return [3,5,1]; } + const arr = makeArray(); + return arr.length;` + ); + Expect(result).toBe(3); + } + @Test("Array intersection access") public arrayIntersectionAccess(): void { const result = util.transpileAndExecute( @@ -36,6 +46,21 @@ export class ArrayTests { Expect(result).toBe(5); } + @Test("Array intersection length") + public arrayIntersectionLength(): void { + const result = util.transpileAndExecute( + `type I = number[] & {foo: string}; + function makeArray(): I { + let t = [3,5,1]; + (t as I).foo = "bar"; + return (t as I); + } + const arr = makeArray(); + return arr.length;` + ); + Expect(result).toBe(3); + } + @TestCase("firstElement()", 3) @TestCase("name", "array") @TestCase("length", 1) @@ -93,4 +118,14 @@ export class ArrayTests { Expect(result).toBe("true:1,2,3,4"); } + + @Test("Array property access") + public arrayPropertyAccess(): void { + const code = + `type A = number[] & {foo?: string}; + const a: A = [1,2,3]; + a.foo = "bar"; + return \`\${a.foo}\${a[0]}\${a[1]}\${a[2]}\`;`; + Expect(util.transpileAndExecute(code)).toBe("bar123"); + } } diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index e7705338a..db8e30d41 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -509,18 +509,6 @@ export class ExpressionTests { .toThrowError(TranspileError, "Unsupported property on array: unknownFunction"); } - @Test("Unsupported array property error") - public unsupportedArrayPropertyError(): void { - const transformer = util.makeTestTransformer(); - - const mockNode: any = { - name: ts.createIdentifier("unknownProperty"), - }; - - Expect(() => transformer.transformArrayProperty(mockNode as ts.PropertyAccessExpression)) - .toThrowError(TranspileError, "Unsupported property on array: unknownProperty"); - } - @Test("Unsupported math property error") public unsupportedMathPropertyError(): void { const transformer = util.makeTestTransformer();