sindresorhus / ow

Function argument validation for humans
https://sindresorhus.com/ow/
MIT License
3.8k stars 105 forks source link

Upgrading to 1.1.0 from older version makes TS complain #248

Closed angelod1as closed 1 year ago

angelod1as commented 1 year ago

My current project uses "ow": "^0.28.1" and it works perfectly.

When I update to "ow": "^1.1.0" TS complains and says Cannot find module 'ow' or its corresponding type declarations..

I'm using VSCode:

Version: 1.74.3 (Universal)
Commit: 97dec172d3256f8ca4bfb2143f3f76b503ca0534
Date: 2023-01-09T17:07:18.579Z
Electron: 19.1.8
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Darwin arm64 22.2.0
Sandboxed: No

Below is some code that doesn't show the warning in the older version but shows in the new one.

import { NextApiRequest, NextApiResponse } from "next"
import assert from "ow"

export type responseItem = {}

export default async function contactHandler(
  req: NextApiRequest,
  res: NextApiResponse<responseItem>,
) {
  const { contact } = req.body
  assert(contact, assert.string.nonEmpty)
  res.send(200)
}
sindresorhus commented 1 year ago

This is either a problem of having an outdated TypeScript version or Next.js not being able to handle this exports field in package.json. Neither of which are problems with this package.

angelod1as commented 1 year ago

Thanks for the explanation.

darkobits commented 1 year ago

FWIW I'm able to reproduce this issue when upgrading to ow >=1.0.0 on Node 18.8.0 and TypeScript 4.9.4 in a vanilla project (no Nest et. al).

This can be fixed by either:

To be fair, Typescript's documentation does indicate that it supports "exports.types", but without setting moduleResolution to nodenext, this behavior does not seem to work.

It might be a reasonable compromise to add a top-level "types" property to ow's package.json to ensure compatibility with consumers who either don't know to set moduleResolution to nodenext or are unable to due to some other requirement of their project. (see comment below)

angelod1as commented 1 year ago

Coming back here because this is still happening in another project. Package.json:

    "@next/font": "13.1.5",
    "@types/node": "18.11.18",
    "@types/react": "18.0.27",
    "@types/react-dom": "18.0.10",
    "eslint": "8.32.0",
    "eslint-config-next": "13.1.5",
    "next": "13.1.5",
    "ow": "^1.1.1",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "typescript": "^4.9.5"

If I don't make what @darkobits wrote there, I get a Cannot find module 'ow' or its corresponding type declarations. error.

If I make it by adding moduleResolution, it errors with:

The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("ow")' call instead.
  To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field `"type": "module"` to '/Users/angelo/Documents/GIT/skoob-to-goodreads/package.json'

If you want to reproduce, this repo has this error.

darkobits commented 1 year ago

After doing some more digging and experimentation:

I think Sindre has already addressed this issue here in his Pure ESM Package gist, but to re-iterate what my take-aways are from that and other sources:

As such, I think this issue is not a problem with ow but rather a very roundabout way of TypeScript telling us it is literally not compatible with ow>=1.0.0 based on our tsconfig.json setup, and the best solution for such users is to pin to an earlier version of ow.

chr4ss12 commented 1 year ago

am not entirely sure what's going on or how this package is built, but it stops us upgrading to more recent versions of ow, perhaps the better approach will be to follow the commonly used patterns what most packages do (am not sure what that is sorry, but they just work without any hassle).

This stops us using the newer version on multiple projects.