Skip to content

Commit

Permalink
Fixed handling private fields with declare keyword
Browse files Browse the repository at this point in the history
Fixes #24
  • Loading branch information
timocov committed Mar 29, 2023
1 parent c4bffe6 commit 081179a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/properties-minifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function isPrivateNonStaticClassMember(symbol: ts.Symbol | undefined): boolean {

return symbol.declarations.some((x: ts.Declaration) => {
// terser / uglify property minifiers aren't able to handle decorators
return (isClassMember(x) && !hasDecorators(x) || isConstructorParameter(x)) && isPrivateNonStatic(x);
return (isClassMember(x) && !hasDecorators(x) || isConstructorParameter(x)) && isPrivateNonStatic(x) && !hasModifier(x, ts.SyntaxKind.DeclareKeyword);
});
}

Expand Down
40 changes: 39 additions & 1 deletion tests/functional-test-cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,52 @@ function checkDiagnosticsErrors(diagnostics: ReadonlyArray<ts.Diagnostic>): void
assert.strictEqual(diagnostics.length, 0, ts.formatDiagnostics(diagnostics, formatDiagnosticsHost).trim());
}

const enum Constants {
NoInputsWereFoundDiagnosticCode = 18003,
}

const parseConfigHost: ts.ParseConfigHost = {
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
readDirectory: ts.sys.readDirectory,
fileExists: ts.sys.fileExists,
readFile: ts.sys.readFile,
};

function getCompilerOptions(configFileName: string): ts.CompilerOptions | null {
if (!fs.existsSync(configFileName)) {
return null;
}

const configParseResult = ts.readConfigFile(configFileName, ts.sys.readFile);

checkDiagnosticsErrors(configParseResult.error !== undefined ? [configParseResult.error] : []);

const compilerOptionsParseResult = ts.parseJsonConfigFileContent(
configParseResult.config,
parseConfigHost,
path.resolve(path.dirname(configFileName)),
undefined,
configFileName
);

// we don't want to raise an error if no inputs found in a config file
// because this error is mostly for CLI, but we'll pass an inputs in createProgram
const diagnostics = compilerOptionsParseResult.errors
.filter((d: ts.Diagnostic) => d.code !== Constants.NoInputsWereFoundDiagnosticCode);

checkDiagnosticsErrors(diagnostics);

return compilerOptionsParseResult.options;
}

describe('Functional tests', () => {
for (const testCase of getTestCases()) {
it(testCase.name, () => {
const program = ts.createProgram({
rootNames: [testCase.inputFileName],
options: {
target: ts.ScriptTarget.ES5,
experimentalDecorators: true,
...getCompilerOptions(path.join(testCase.inputFileName, '..', 'tsconfig.json')),
},
});

Expand Down
9 changes: 9 additions & 0 deletions tests/test-cases/useDefineForClassFields-and-declare/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Class {
public declare publicField: number;
protected declare protectedField: number;
private declare privateField: number;

public method() {
console.log(this.publicField, this.protectedField, this.privateField);
}
}
13 changes: 13 additions & 0 deletions tests/test-cases/useDefineForClassFields-and-declare/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var Class = /** @class */ (function () {
function Class() {
}
Object.defineProperty(Class.prototype, "method", {
enumerable: false,
configurable: true,
writable: true,
value: function () {
console.log(this.publicField, this.protectedField, this.privateField);
}
});
return Class;
}());
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"useDefineForClassFields": true
}
}

0 comments on commit 081179a

Please sign in to comment.