Symbol type is incorrectly generalized when used as a property value of an object literal
See original GitHub issueTypeScript Version: 3.7.5
Search Terms: symbol infer type
Expected behavior:
Symbol const uniqueSymbol = Symbol()
when used as property value in an object literal is inferred as unique type typeof uniqueSymbol
.
Actual behavior:
Symbol const uniqueSymbol = Symbol()
when used as property value in an object literal is inferred as general type symbol
.
Related Issues:
Code
const uniqueSymbol = Symbol()
// Example of incorrect inference (unique symbol is generalized to type `symbol`)
const foo = {
prop: uniqueSymbol,
}
type Foo = typeof foo // { prop: symbol }
// Workarounds for incorrect behavior
const bar = {
prop: uniqueSymbol as typeof uniqueSymbol,
}
type Bar = typeof bar // { prop: typeof uniqueSymbol }
const genericFactory = <T>(value: T) => ({ prop: value })
const baz = genericFactory(uniqueSymbol)
type Baz = typeof baz // { prop: typeof uniqueSymbol }
Output
"use strict";
const uniqueSymbol = Symbol();
// Example of incorrect inference (unique symbol is generalized to type `symbol`)
const foo = {
prop: uniqueSymbol,
};
// Workarounds for incorrect behavior
const bar = {
prop: uniqueSymbol,
};
const genericFactory = (value) => ({ prop: value });
const baz = genericFactory(uniqueSymbol);
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
}
Playground Link: Provided
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Symbol type - The Modern JavaScript Tutorial
A “symbol” represents a unique identifier. A value of this type can be created using Symbol() : let id = Symbol();.
Read more >TypeError: can't assign to property "x" on "y": not an object
In strict mode, a TypeError is raised when attempting to create a property on primitive value such as a symbol, a string, a...
Read more >Why am I getting an error "Object literal may only specify ...
Usually this error means you have a bug (typically a typo) in your code, or in the definition file. The right fix in...
Read more >14. New OOP features besides classes - Exploring JS
However, it also includes new features for object literals and new utility ... One use case for property value shorthands are multiple return...
Read more >You Don't Know JS: this & Object Prototypes - GitHub Pages
Type. Objects are the general building block upon which much of JS is built. ... If you use any other value besides a...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Same is true of other literal types:
prop
is a mutable object member. Assigning a singleton type to a mutable member is usually not useful, so we widen at mutable positions. Do note, there is no way to declare an immutable object property (only class fields).It seems that main issue that I’ve described works consistently for primitive types but at the same time TS as a language lacks other mechanisms for type
symbol
that allow to avoid generalization of variable that is a specific symbol. Please take a look at following techniques:Playground link
Both
as const
casting and explicit type declaration cannot be used onsymbol
s.