This code snippet presents an interesting scenario that may not be immediately obvious upon first glance.
Let's delve into it:
const s = Symbol();
type DictNumber = {
[key: number]: string;
}
const dictNumber: DictNumber = {
1: 'andy', // valid
'foo': 'bar', // invalid
[s]: 'baz', // valid
}
Now, let's attempt to rectify the issue with the foo
key:
const dictNumber: DictNumber = {
1: 'andy', // valid
'2': 'bar', // valid
[s]: 'baz', // invalid
}
It appears that there is actually an error in the code, but due to how error highlighting works, it may not be immediately noticeable.
The TypeScript team likely designed it this way for improved performance. Unnecessary validation is avoided if an error has already been detected.
A similar situation arises with const dictSymbol: DictSymbol
. Feel free to make replacements and observe the outcomes.
Only DictString
seems to defy our expectations by not showing any errors:
const s = Symbol();
type DictSymbol = Record<symbol, string>
type DictString = Record<string, string>
let dictString: DictString = {
a: 'baz',
}
let dictSymbol: DictString = {
[s]: 'baz', // no error , although there should be
}
dictString = dictSymbol // valid
dictSymbol = dictString // valid
To ensure safety, consider using interface
instead of Record<K,V>
:
const s = Symbol();
interface DictSymbol {
[sym: symbol]: string
}
type DictString = Record<string, string>
let dictString: DictSymbol = {
a: 'baz', // error
}
let dictSymbol: DictString = {
[s]: 'baz', // no error , although there should be
}
dictString = dictSymbol // valid
dictSymbol = dictString // error
Converting DictString
to an interface
will yield more errors:
const s = Symbol();
interface DictSymbol {
[sym: symbol]: string
}
interface DictString {
[str: string]: string
}
let dictString: DictSymbol = {
a: 'baz', // error
}
let dictSymbol: DictString = {
[s]: 'baz', // still no error
}
dictString = dictSymbol // valid
dictSymbol = dictString // error
The absence of an error in certain cases remains perplexing. One would expect an error here:
let dictSymbol: DictString = {
[s]: 'baz', // still no error
}