Comments (7)
To be even more explicit, this
// @filename: defines.d.ts
export const mySymbol: unique symbol;
// @filename: usage.ts
import {mySymbol} from "./defines.js"
export class Foo {
[mySymbol]() {}
}
is something you want to allow because it's how symbols are meant to be used, but
// @filename: defines.d.ts
export const mySymbol: string;
// @filename: usage.ts
import {mySymbol} from "./defines.js"
export class Foo {
[mySymbol]() {}
}
is something you need to forbid because you don't know if mySymbol
conflicts with anything. And when you only look at usage.ts
, these two cases are identical. So you're either conservative and forbid basically all computed names (very bad for usability), incredibly loose and allow most computed names (which is a big footgun for anyone relying on the output computed name actually working/existing when transformed into a type), or you slice it in some weird way to sometimes work and sometimes not based on some common usecase heuristics.
from typescript.
@dragomirtitian @weswigham here's a fun one for y'all 🙃
from typescript.
For computed properties we allow them to be used in isolated declarations even if we can't determine the type is valid locally. This was due to the fact that computed properties with unique symbols would otherwise be completely unusable with isolated declarations.
In transpileDecalarations
the checker should only be used when needed. In this case the checker will not actually find a type for Symbol.iterator
so it will complain. I think since transpileDecalarations
uses noChecck
it should probably fall back on the isolated declaration test and just emit the entity name even if it can't check the type is correct. @weswigham thought?
from typescript.
it should probably fall back on the isolated declaration test and just emit the entity name even if it can't check the type is correct
It is. The issue is that the check for the ID error (in visitDeclarationSubtree
in declarations.ts
) relies on elements of the Symbol
global resolving, in this case. Specifically, that resolver.isEntityNameVisible
check in the condition. If the checker isn't running and you have no other files in the program, the name isn't gonna resolve for a missing global. Yeah, that would be a checker error if the checker was running in the same noResove
-ish single-file mode, but if you're not even capturing those... ??? The error behavior here is checker dependent because of the entity name lookup - hence the difference in command-line (where the global resolves) and API (where it doesn't) behavior.
Symbols are a big hole in isolatedDeclarations
usability that we don't have great answers for right now. For builtin symbols, I could easily remove the error by passing a more complete lib
into the transpileDeclarations
program, so Symbol.iterator
is recognized as a valid late-bound property, but that's basically a stop-gap. Custom symbols like
const sym = Symbol();
export class Foo {
public [sym]() {
return {
next: () => ({ value: 42, done: false }),
};
}
}
I've currently patched into emitting "correctly", but still issuing the isolatedDeclarations
error - I imagine this case should be similar. The ID error should appear in all cases (even when the name fails to resolve), but the emit should be reasonably sane.
from typescript.
still issuing the isolatedDeclarations error
Would you happen to know of a clean and concise way to annotate code following this pattern to satisfy isolatedDeclarations? IIRC they can't be suppressed by @ts-expect-error
(on my phone so can't validate quickly)
from typescript.
The issue with the symbol computed names is that there isn't one - to write it you'd still need a type with a symbol computed name, which then has the same issue. Call it a flaw with the whole idea that you can do declaration emit without expression checking, since computed names mean even types can rely on (nonlocal!) expression evaluation - minimally you need to make breaking assumptions that expressions in computed names probably resolve to valid property names that probably don't conflict with other property names.
Or you give up and do some limited checking-like analysis - looking for references to the global Symbol
and members thereof. This is probably the direction we'll go - just finding the right way to slice the analysis is weird. It's unclear how much of the lib
we should bring in.
from typescript.
Hm. Wonder if it would be too special casey to look for expressions that match the pattern Symbol.iterator satisfies unique symbol
and emit without error in those cases
from typescript.
Related Issues (20)
- Assignation of incorrect value doesn't type error HOT 1
- TS 5.5.0-beta Regression: generated .d.ts is not compatible HOT 2
- [isolatedDeclarations] Should imported JSON files be emitted when "resolveJsonModules", "emitDeclarationOnly", and "isolatedDeclarations" are all enabled?
- Google feedback on TS 5.5-beta HOT 4
- Design Meeting Notes, 5/28/2024 HOT 3
- Template literal type reduction is inconsistent (regression in 5.5-beta) HOT 2
- TypeScript emits d.ts file that is invalid for complex mapped type.
- Object.values and Object.entries return any instead of the actual value when object values are an intersection HOT 3
- TypeScript Dount HOT 3
- [isolatedDeclarations] An option like disableSourceOfProjectReferenceRedirect, but configurable on the referenced project's end HOT 6
- Incorrect 'd.ts' with 'Cannot find name' error HOT 1
- Mapped types doesn't map the key value for methods when mapping over a generic instantiated with an array HOT 5
- texSubImage2D missing WebGL2 syntax
- Non-exported recursive type alias is inlined until it falls back to any in declarations HOT 2
- Spread of two generic array types is misreported as having length 2
- TS5.5-beta injects a random `@ts-expect-error` comment in the generated `.d.ts` files HOT 3
- [ts-beta 5.5] Function declarations are not exported when targeting commonJS - js emit regression HOT 4
- Tuple Restriction Issue: Inconsistent Behavior with Array Methods HOT 2
- `never` return type not respected on function called on object with inferred type HOT 2
- Type narrowing not work in forEach callback HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript.