phetsims / axon

Axon provides powerful and concise models for interactive simulations, based on observable Properties and related patterns.
MIT License
10 stars 8 forks source link

Convert units.ts to a TypeScript type #452

Closed pixelzoom closed 1 month ago

pixelzoom commented 2 months ago

... so that we can take advantage of type checking for Property's units option, instead of waiting for a runtime failure.

units.ts would be replaced by Units.ts, something like this:

export const UnitsValues = [
    '1/(cm*M)', // molar absorptivity
    '%', // percent
    'A', // amperes
    'AMU', // atomic mass unit
    'atm', // atmospheres
    'AU', // astronomical units
    'AU^2', // astronomical units squared
    'cm', // centimeters
    'cm^2', // centimeters squared
    'C', // coulombs
    '\u00B0', // °, degrees (angle)
    '\u00B0C', // °C, degrees Celsius
    'F', // farad
    '\u00B0F', // °F, degrees Fahrenheit
    'g', // grams
    'G', // gauss
    'Hz', // hertz
    'J', // Joules
    'K', // Kelvin
    'kg', // kilograms
    'kg/m^3', // kg/cubic meter
    'kg/L', // kg/liter
    'kg\u00b7m/s', // kg·m/s, kilogram-meters/second
    'km/s',
    'kPa', // kilopascals
    'L',
    'L/s',
    'm', // meters
    'm^3', // cubic meter
    'm/s', // meters/second
    'm/s/s', // meters/second/second
    'm/s^2', // meters/seconds squared
    'mA', // milliampere
    'mm', //millimeters
    'mol',
    'mol/L',
    'mol/s',
    'M', // molar
    'N', // Newtons
    'N/m', // Newtons/meter
    'nm', // nanometers
    'nm/ps', // nanometers/picosecond
    'N\u00b7s/m', // N·s/m, Newton-seconds/meter
    '\u2126', // Ω, ohms - don't use the one in MathSymbols to prevent a dependency on scenery-phet
    '\u2126\u00b7cm', // Ω·cm, ohm-centimeters
    'Pa\u00b7s', // Pascal-seconds
    'particles/ps', // particles/picosecond
    'pm', // picometers
    'pm/ps', // picometers/picosecond
    'pm/s', // picometers/second
    'pm/s^2', // picometers/second-squared
    'pm^3', // picometers cubed
    'ps', // picoseconds
    'radians', // radians - note this has the same abbreviation as the radiation term "rad" so we use the full term
    'radians/s', // radians/second
    'radians/s^2', // radians/second^2
    'rpm', // revolutions per minute
    's', // seconds
    'V', // volts
    'view-coordinates/s',
    'W', // watts
    'Wb', // weber
    'years' // years
] as const;

export type Units = ( typeof UnitsValues )[number];

And in ReadOnlyProperty.ts:

- import units from './units.js';
+ import units from './Units.js';
...
export type ReadOnlyPropertyState<StateType> = {
  value: StateType;

  // Only include validValues if specified, so they only show up in PhET-iO Studio when supplied.
  validValues: StateType[] | null;

-  units: string | null;
+  units: Units | null;
};
jessegreenberg commented 1 month ago

@zepumph offered to do this one, thank you!

zepumph commented 1 month ago

Hows that @pixelzoom?

zepumph commented 1 month ago

The only thing I didn't like was the type cast in

https://github.com/phetsims/gas-properties/blob/583124a92b1b71163c5d645c41dd6310fe33c621/js/diffusion/model/DiffusionParticleSystem.ts#L37

I tried using satisfies Units, but it didn't cast it into a Units (though it would type error if pm wasn't a unit). Perhaps as is best?

pixelzoom commented 1 month ago

The only thing I didn't like was the type cast in ...

I eliminated the need for that cast in https://github.com/phetsims/gas-properties/commit/46dd550797647a29f45be62291c415805a43bff1.

units.ts looks great, thanks for doing this. At first I wasn't sure if const units was still needed. I had originally thought that it would be deleted, and the file renamed to Units.ts. But I guess that const units still has value for JavaScript code.

Closing.