Skip to content

Commit f9bc20a

Browse files
committed
Fixed incorrect error on intersected number and string types
1 parent 96c3f8d commit f9bc20a

File tree

4 files changed

+43
-24
lines changed

4 files changed

+43
-24
lines changed

src/transformation/builtins/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ import { assume } from "../../utils";
44
import { TransformationContext } from "../context";
55
import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib";
66
import { getIdentifierSymbolId } from "../utils/symbols";
7-
import { isArrayType, isFunctionType, isNumberType, isStandardLibraryType, isStringType } from "../utils/typescript";
7+
import {
8+
hasStandardLibrarySignature,
9+
isArrayType,
10+
isFunctionType,
11+
isNumberType,
12+
isStandardLibraryType,
13+
isStringType,
14+
} from "../utils/typescript";
815
import { PropertyCallExpression } from "../visitors/call";
916
import { checkForLuaLibType } from "../visitors/class/new";
1017
import { transformArrayProperty, transformArrayPrototypeCall } from "./array";
@@ -85,11 +92,11 @@ export function transformBuiltinCallExpression(
8592
}
8693
}
8794

88-
if (isStringType(context, ownerType)) {
95+
if (isStringType(context, ownerType) && hasStandardLibrarySignature(context, node)) {
8996
return transformStringPrototypeCall(context, node);
9097
}
9198

92-
if (isNumberType(context, ownerType)) {
99+
if (isNumberType(context, ownerType) && hasStandardLibrarySignature(context, node)) {
93100
return transformNumberPrototypeCall(context, node);
94101
}
95102

src/transformation/utils/typescript/index.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ export function isFirstDeclaration(context: TransformationContext, node: ts.Vari
4343
return firstDeclaration === node;
4444
}
4545

46+
function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean {
47+
const sourceFile = declaration.getSourceFile();
48+
if (!sourceFile) {
49+
return false;
50+
}
51+
52+
return context.program.isSourceFileDefaultLibrary(sourceFile);
53+
}
54+
4655
export function isStandardLibraryType(
4756
context: TransformationContext,
4857
type: ts.Type,
@@ -59,12 +68,16 @@ export function isStandardLibraryType(
5968
return true;
6069
}
6170

62-
const sourceFile = declaration.getSourceFile();
63-
if (!sourceFile) {
64-
return false;
65-
}
71+
return isStandardLibraryDeclaration(context, declaration);
72+
}
6673

67-
return context.program.isSourceFileDefaultLibrary(sourceFile);
74+
export function hasStandardLibrarySignature(
75+
context: TransformationContext,
76+
callExpression: ts.CallExpression
77+
): boolean {
78+
const signature = context.checker.getResolvedSignature(callExpression);
79+
80+
return signature && signature.declaration ? isStandardLibraryDeclaration(context, signature.declaration) : false;
6881
}
6982

7083
export function inferAssignedType(context: TransformationContext, expression: ts.Expression): ts.Type {

test/unit/builtins/numbers.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,10 @@ test.each(cases)("isNaN(%p)", value => {
6767
test.each(cases)("isFinite(%p)", value => {
6868
util.testExpressionTemplate`isFinite(${value} as any)`.expectToMatchJsResult();
6969
});
70+
71+
test("number intersected method", () => {
72+
util.testFunction`
73+
type Vector = number & { normalize(): Vector };
74+
return ({ normalize: () => 3 } as Vector).normalize();
75+
`.expectToMatchJsResult();
76+
});

test/unit/builtins/string.spec.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
1-
import { UnsupportedProperty } from "../../../src/transformation/utils/errors";
21
import * as util from "../../util";
32

4-
test("Unsupported string function", () => {
5-
util.testExpression`"test".testThisIsNoMember()`
6-
.disableSemanticCheck()
7-
.expectToHaveDiagnosticOfError(UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub));
8-
});
9-
103
test("Supported lua string function", () => {
11-
const tsHeader = `
12-
declare global {
13-
interface String {
14-
upper(): string;
15-
}
16-
}
17-
`;
18-
19-
util.testExpression`"test".upper()`.setTsHeader(tsHeader).expectToEqual("TEST");
4+
util.testExpression`"test".toUpperCase()`.expectToEqual("TEST");
205
});
216

227
test.each([[], [65], [65, 66], [65, 66, 67]])("String.fromCharCode (%p)", (...args) => {
@@ -287,3 +272,10 @@ describe.each(["trim", "trimEnd", "trimRight", "trimStart", "trimLeft"])("string
287272
util.testExpression`${util.formatCode(testString)}.${trim}()`.expectToMatchJsResult();
288273
});
289274
});
275+
276+
test("string intersected method", () => {
277+
util.testFunction`
278+
type Vector = string & { abc(): Vector };
279+
return ({ abc: () => "a" } as Vector).abc();
280+
`.expectToMatchJsResult();
281+
});

0 commit comments

Comments
 (0)