Closed
Description
Recognizing Symbol.hasInstance
in instanceof
Narrowing
- Previous discussion at Design Meeting Notes, 8/9/2023 #55325
- TypeScript currently doesn't recognize anything about
Symbol.hasInstance
when performing aninstanceof
. - PR considers
[Symbol.hasInstance]
-declared methods that are declared as type guards. - When you do this, it changes narrowing very slightly.
- Kind of merges the behavior of type predicates narrowing and narrowing via derivedness checks.
- Specific exceptions regarding
any
.
- Seems okay, just needs review.
Improve portability of resolution-mode assertions automatically emitted in nodenext
- Now seeing
/// <reference types="..." />
directives getting generated withresolution-mode="require"
in declaration emit. - Not everyone is using the same TS version, resolution options.
- Need to either make TS more lenient or generate these resolution-mode attributes appear less-often.
- TypeScript will generate these
/// <reference types />
directives to ensure broader compatibility for consumers. - When TypeScript encounters
/// <reference types="chai" />
from an ES module, we try to do an import tochai
, not find a.
export inchai
'spackage.json
, and fall back to the CommonJS types anyway. - Could we just support
resolution-mode
regardless of any settings?- Probably, and could even for
import type
.
- Probably, and could even for
- Very weird that the
types
compiler option doesn't support this.
Tracking Recursion Identity of Homomorphic Mapped Types Based On Their Target Symbol
type Id<T> = { [K in keyof T]: Id<T[K]> };
type Foo1 = Id<{ x: { y: { z: { a: { b: { c: number } } } } } }>;
type Foo2 = Id<{ x: { y: { z: { a: { b: { c: string } } } } } }>;
declare const foo1: Foo1;
const foo2: Foo2 = foo1; // Errors with PR, previously didn't.
-
When tracking if
Foo2
is compatible withFoo1
, we would say "We sawId<*Something*>
too many times".- This was based on using the identity of
Id
itself when tracking recursive instantiation.
- This was based on using the identity of
-
Now, if
*Something*
is a type with a symbol, we use that as the identity. -
Breaks the raphael package on DefinitelyTyped. Can be fixed with
in out
.- Alternative fix is for these mapped types to be broken up into named types.
-
How does this work for nested mapped types?
type Expand<T> = { [K in keyof T]: Expand<Expand<T[K]>> };
- We drill through to find the identity.
- Need a test case.
-
Technically you can still hit issues between non-identical mapped types.
Enabling fetch
in Node.js
DefinitelyTyped/DefinitelyTyped#60924
- The DOM has a global
fetch
function and a few related global classes. - As of Node 20, Node.js has a compatible global
fetch
. - They're compatible, but not identical.
- This is a problem because a lot of users with front-end projects accidentically end up including Node's types - either via misconfiguration or a "rogue" package in
node_modules
. - Two solutions.
- One is through a level of indirection where the global types extend aliases from Unici. They are conditionally extended from Undici based on whether the global scope includes some amount of information from the DOM.
- Downside: hard dependency on Undici, which is fairly large as a package. 1MB because it doesn't just include types. Have to worry about versioning.
- Technically, Undici is shipped within Node.js, but only kinda exposed. Similarly,
fs.rm
is actually rimraf under the hood. (!)
- Alternatively, duplicate all the contents of
fetch
. About 600 lines, so not small.
- One is through a level of indirection where the global types extend aliases from Unici. They are conditionally extended from Undici based on whether the global scope includes some amount of information from the DOM.