Repository: chartjs/Chart.js
File: src/helpers/helpers.options.ts (TypeScript)

Code before:
 * @returns The effective line height in pixels (size * 1.2 if value is invalid).
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
 * @since 2.7.0
 */
export function toLineHeight(value: number | string, size: number): number {
  const matches = ('' + value).match(LINE_HEIGHT);
  if (!matches || matches[1] === 'normal') {
    return size * 1.2;
  }

  value = +matches[2];

  switch (matches[3]) {
    case 'px':
      return value;
    case '%':
      value /= 100;
      break;
    default:
      break;
  }

  return size * value;
}

const numberOrZero = (v: number) => +v || 0;

/**
 * @param value
 * @param props
 */
export function _readValueToProps<K extends string>(value: number | Record<K, number>, props: K[]): Record<K, number>;
export function _readValueToProps<K extends string, T extends string>(value: number | Record<K & T, number>, props: Record<T, K>): Record<T, number>;
export function _readValueToProps(value: number | Record<string, number>, props: string[] | Record<string, string>) {
  const ret = {};
  const objProps = isObject(props);
  const keys = objProps ? Object.keys(props) : props;
  const read = isObject(value)
    ? objProps
      ? prop => valueOrDefault(value[prop], value[props[prop]])
      : prop => value[prop]
    : () => value;

  for (const prop of keys) {
    ret[prop] = numberOrZero(read(prop));
  }
  return ret;
}

/**
 * Converts the given value into a TRBL object.

Review comment (suggestion):
The implementation works with anything(?), should we allow a bit wider input?

![image](https://user-images.githubusercontent.com/27971921/199038002-254fb192-f27e-405b-bd19-ae6d41c43388.png)



Code after:
 * @returns The effective line height in pixels (size * 1.2 if value is invalid).
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height
 * @since 2.7.0
 */
export function toLineHeight(value: number | string, size: number): number {
  const matches = ('' + value).match(LINE_HEIGHT);
  if (!matches || matches[1] === 'normal') {
    return size * 1.2;
  }

  value = +matches[2];

  switch (matches[3]) {
    case 'px':
      return value;
    case '%':
      value /= 100;
      break;
    default:
      break;
  }

  return size * value;
}

const numberOrZero = (v: unknown) => +v || 0;

/**
 * @param value
 * @param props
 */
export function _readValueToProps<K extends string>(value: number | Record<K, number>, props: K[]): Record<K, number>;
export function _readValueToProps<K extends string, T extends string>(value: number | Record<K & T, number>, props: Record<T, K>): Record<T, number>;
export function _readValueToProps(value: number | Record<string, number>, props: string[] | Record<string, string>) {
  const ret = {};
  const objProps = isObject(props);
  const keys = objProps ? Object.keys(props) : props;
  const read = isObject(value)
    ? objProps
      ? prop => valueOrDefault(value[prop], value[props[prop]])
      : prop => value[prop]
    : () => value;

  for (const prop of keys) {
    ret[prop] = numberOrZero(read(prop));
  }
  return ret;
}

/**
 * Converts the given value into a TRBL object.