Skip to content

Commit

Permalink
fix(format): 'typescript/es6-declarations' return type (#681)
Browse files Browse the repository at this point in the history
This change fixes an issue where all variables exported from 'typescript/es6-declarations' are assumed to be of type `string`. Instead, it adds some *basic* type checking for a few known values, and will fall back to `any` if the type can't be easily determined.
  • Loading branch information
Dru89 committed Aug 19, 2021
1 parent bfc204c commit 0cf6c52
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 3 deletions.
42 changes: 42 additions & 0 deletions __tests__/common/formatHelpers/getTypeScriptType.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

const getTypeScriptType = require('../../../lib/common/formatHelpers/getTypeScriptType');

describe('common', () => {
describe('formatHelpers', () => {
describe('getTypeScriptType', () => {
it('should recognize basic types', () => {
expect(getTypeScriptType('a string')).toEqual('string');
expect(getTypeScriptType(3.14159)).toEqual('number');
expect(getTypeScriptType(true)).toEqual('boolean');
});

it('should recognize arrays of basic types', () => {
expect(getTypeScriptType(['an', 'array', 'of', 'strings'])).toEqual('string[]');
expect(getTypeScriptType([3.14159])).toEqual('number[]');
expect(getTypeScriptType([true, false, true, true])).toEqual('boolean[]');
});

it('should default to any, if no type is determined', () => {
expect(getTypeScriptType({})).toEqual('any');
expect(getTypeScriptType([{}])).toEqual('any[]');
expect(getTypeScriptType(['string', 3.14, false])).toEqual('any[]');
});

it('should support nested arrays', () => {
expect(getTypeScriptType([[100, 200], [300, 400]])).toEqual('number[][]');
})
});
});
});
53 changes: 53 additions & 0 deletions lib/common/formatHelpers/getTypeScriptType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/

/**
* Given some value, returns a basic valid TypeScript type for that value.
* Supports numbers, strings, booleans, and arrays of any of those types.
*
* @memberof module:formatHelpers
* @example
* ```javascript
* StyleDictionary.registerFormat({
* name: 'myCustomFormat',
* formatter: function({ dictionary, options }) {
* return dictionary.allProperties.map(function(prop) {
* var to_ret_prop = 'export const ' + prop.name + ' : ' + getTypeScriptType(prop.value) + ';';
* if (prop.comment)
* to_ret_prop = to_ret_prop.concat(' // ' + prop.comment);
* return to_ret_prop;
* }).join('\n');
* }
* });
*
* @param {*} value A value to check the type of.
* @return {String} A valid name for a TypeScript type.
* ```
*/
function getTypeScriptType(value) {
if (Array.isArray(value)) {
if (value.length > 0) {
const firstValueType = getTypeScriptType(value[0]);
if (value.every((v) => getTypeScriptType(v) === firstValueType)) {
return firstValueType + '[]';
}
}
return 'any[]';
}

const type = typeof value;
if (['string', 'number', 'boolean'].includes(type)) return type;
return 'any';
}

module.exports = getTypeScriptType;
3 changes: 2 additions & 1 deletion lib/common/formatHelpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
*
* @module formatHelpers
*/
module.exports = {
module.exports = {
createPropertyFormatter: require('./createPropertyFormatter'),
fileHeader: require('./fileHeader'),
formattedVariables: require('./formattedVariables'),
getTypeScriptType: require('./getTypeScriptType'),
iconsWithPrefix: require('./iconsWithPrefix'),
sortByReference: require('./sortByReference'),
sortByName: require('./sortByName'),
Expand Down
4 changes: 2 additions & 2 deletions lib/common/formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const fs = require('fs');
const path = require('path');
const _template = require('lodash/template');
const GroupMessages = require('../utils/groupMessages');
const { fileHeader, formattedVariables, iconsWithPrefix, minifyDictionary, sortByReference, createPropertyFormatter, sortByName } = require('./formatHelpers');
const { fileHeader, formattedVariables, getTypeScriptType, iconsWithPrefix, minifyDictionary, sortByReference, createPropertyFormatter, sortByName } = require('./formatHelpers');

const SASS_MAP_FORMAT_DEPRECATION_WARNINGS = GroupMessages.GROUP.SassMapFormatDeprecationWarnings;

Expand Down Expand Up @@ -393,7 +393,7 @@ module.exports = {
'typescript/es6-declarations': function({dictionary, file}) {
return fileHeader({file}) +
dictionary.allProperties.map(function(prop) {
var to_ret_prop = 'export const ' + prop.name + ' : string;';
var to_ret_prop = 'export const ' + prop.name + ' : ' + getTypeScriptType(prop.value) + ';';
if (prop.comment)
to_ret_prop = to_ret_prop.concat(' // ' + prop.comment);
return to_ret_prop;
Expand Down

0 comments on commit 0cf6c52

Please sign in to comment.