I have a script that uses date-fns. This script worked fine in Deno v1.4.6, but after I upgraded to v1.5.0, it doesn't work.
Create a file main.ts with the following content:
import { formatISO } from "https://deno.land/x/[email protected]/index.js";
const d = new Date();
console.log(formatISO(d));
Then run it by deno run main.ts. The output I've got is:
Check file:///tmp/deno-bug/main.ts
error: TS2555 [ERROR]: Expected at least 2 arguments, but got 1.
console.log(formatISO(d));
~~~~~~~~~~~~
at file:///tmp/deno-bug/main.ts:4:13
An argument for 'dirtyOptions' was not provided.
export default function formatISO(dirtyDate, dirtyOptions) {
~~~~~~~~~~~~
at https://deno.land/x/[email protected]/formatISO/index.js:43:46
Check file:///tmp/deno-bug/main.ts
2020-10-31T11:43:48+09:00
cc @kitsonk
For some reason we are type checking JS.
@magurotuna As a workaround until this is fixed, you can use a compiler hint (first line):
// @deno-types="https://unpkg.com/[email protected]/typings.d.ts"
import { formatISO } from "https://deno.land/x/[email protected]/index.js";
const d = new Date();
console.log(formatISO(d));
This will also improve your developer experience if you are using something like VS Code + the deno extension.
Aside: Not sure why the typings are excluded from that repo in deno.land/x. They are in the GitHub repo and being published to npm.
For some reason we are type checking JS.
We aren't type checking JS. The JavaScript though is influencing the types in TypeScript. I believe that the current behaviour is actually the desired behaviour. The example code provides JSDoc:
/**
* @name formatISO
* @category Common Helpers
* @summary Format the date according to the ISO 8601 standard (http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003169814.htm).
*
* @description
* Return the formatted date string in ISO 8601 format. Options may be passed to control the parts and notations of the date.
*
* @param {Date|Number} date - the original date
* @param {Object} [options] - an object with options.
* @param {'extended'|'basic'} [options.format='extended'] - if 'basic', hide delimiters between date and time values.
* @param {'complete'|'date'|'time'} [options.representation='complete'] - format date, time with time zone, or both.
* @returns {String} the formatted date string
* @throws {TypeError} 1 argument required
* @throws {RangeError} `date` must not be Invalid Date
* @throws {RangeError} `options.format` must be 'extended' or 'basic'
* @throws {RangeError} `options.represenation` must be 'date', 'time' or 'complete'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format (UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52))
* //=> '2019-09-18T19:00:52Z'
*
* @example
* // Represent 18 September 2019 in ISO 8601, short format (UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { format: 'basic' })
* //=> '20190918T190052'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format, date only:
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'date' })
* //=> '2019-09-18'
*
* @example
* // Represent 18 September 2019 in ISO 8601 format, time only (UTC):
* const result = formatISO(new Date(2019, 8, 18, 19, 0, 52), { representation: 'time' })
* //=> '19:00:52Z'
*/
export default function formatISO(dirtyDate, dirtyOptions) {
if (arguments.length < 1) {
throw new TypeError(
`1 argument required, but only ${arguments.length} present`
)
}
Because it uses a syntax that isn't actually compliant with JSDoc, TypeScript doesn't understand the second argument is actually optional.
If you configure something similar under tsc like the following:
main.ts
import formatIso from "./api";
formatIso("test");
api.js
/**
*
* @param {Date|Number} date - the original date
* @param {Object} [options] - an object with options.
*/
export default function formatIso(dirtyDate, dirtyOptions) {
console.log(dirtyDate, dirtyOptions);
}
And configure allowJs and strict in a tsconfig.json, you will get the following emitted:
main.ts:3:1 - error TS2554: Expected 2 arguments, but got 1.
3 formatIso("test");
~~~~~~~~~~~~~~~~~
api.js:6:46
6 export default function formatIso(dirtyDate, dirtyOptions) {
~~~~~~~~~~~~
An argument for 'dirtyOptions' was not provided.
Found 1 error.
So it was broken before and we didn't realise it. @jsejcksn "workaround" is the proper fix, but actually datefns in deno.land/x/ should actually point to a CDN that provides X-TypeScript-Types like SkyPack.
@jsejcksn
thanks for the workaround! That way I have made it work in v1.5.0. 馃憤
Since it is working as designed, I will close this.
Most helpful comment
We aren't type checking JS. The JavaScript though is influencing the types in TypeScript. I believe that the current behaviour is actually the desired behaviour. The example code provides JSDoc:
Because it uses a syntax that isn't actually compliant with JSDoc, TypeScript doesn't understand the second argument is actually optional.
If you configure something similar under
tsclike the following:main.ts
api.js
And configure
allowJsandstrictin atsconfig.json, you will get the following emitted:So it was broken before and we didn't realise it. @jsejcksn "workaround" is the proper fix, but actually
datefnsindeno.land/x/should actually point to a CDN that providesX-TypeScript-Typeslike SkyPack.