UNPKG

style-dictionary

Version:

Style once, use everywhere. A build system for creating cross-platform styles.

91 lines (84 loc) 3.12 kB
/* * 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. */ /** * @typedef {import('../../../types/Config.d.ts').LocalOptions} Options * @typedef {import('../../../types/Config.d.ts').Config} Config */ /** * Given some value, returns a basic valid TypeScript type for that value. * Supports numbers, strings, booleans, arrays and objects of any of those types. * * @memberof module:formatHelpers * @name getTypeScriptType * @example * ```javascript * StyleDictionary.registerFormat({ * name: 'myCustomFormat', * format: function({ dictionary, options }) { * return dictionary.allTokens.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 {any} value A value to check the type of. * @param {Config & {outputStringLiterals?: boolean}} [options] * @return {String} A valid name for a TypeScript type. * */ export default function getTypeScriptType(value, options) { const { outputStringLiterals = false } = options ?? {}; if (Array.isArray(value)) return getArrayType(value); if (typeof value === 'object') return getObjectType(value); if (outputStringLiterals && typeof value === 'string') return `"${value.replace(/"/g, '\\"')}"`; if (['string', 'number', 'boolean'].includes(typeof value)) return typeof value; return 'any'; } /** * @param {Object} value An object with uknown type properties * @returns {String} A representation of the type model for the passed object */ function getObjectType(value) { const entries = Object.entries(value); return `{ ${entries .map(([key, property], index) => { const isLast = entries.length === index + 1; return `${key}: ${getTypeScriptType(property)}${!isLast ? ', ' : ''}`; }) .join('')} }`; } /** * @param {any[]} arr An array to check each property of * @returns {String} A valid type for the passed array and it's items */ function getArrayType(arr) { if (arr.length > 0) { const firstValueType = getTypeScriptType(arr[0]); if (arr.every((v) => getTypeScriptType(v) === firstValueType)) { return firstValueType + '[]'; } else { return `(${Array.from( new Set( arr.map((item, index) => { const isLast = arr.length === index + 1; return `${getTypeScriptType(item)}${!isLast ? ' | ' : ''}`; }), ), ).join('')})[]`; } } return 'any[]'; }