Description
Bug Report
I have a data store that uses prefixes to store different types of data. One of the types is "preferences".
data = {
"preferences.a": string,
"preferences.b": number
}
I have a getter interface for preferences that allows the user to query without the prefix:
type PreferencesSchema = {
a: string,
b: number
}
function getPreference<KeyT extends keyof PreferencesSchema>(key: KeyT): PreferencesSchema[KeyT] {
return data[`preferences.${key}`];
}
Unfortunately, this gives an error, because TS looks for a
and b
on the data
instead of the actual indexes preferences.a
and preferences.b
. I understand template literal types are relatively new, but I think in this case, the compiler should see that the prefixed keys are being used and that the associated values are the same as the value types in the preference schema.
I found a similar looking issue: #13948, but I don't think this error can be attributed to type-widening.
🔎 Search Terms
template literal missing properties
🕗 Version & Regression Information
- This changed between versions 4.3.5 and 4.4.4 (4.3.5 still gives a
noImplicitAny
error, but the introduction of template literal types makes this issue arise even without strict checks)
⏯ Playground Link
Playground link with relevant code
💻 Code
type PreferencesSchema = {
a: string,
b: number
}
interface DataSchema {
"preferences.a": string,
"preferences.b": number
}
const data: DataSchema = {
"preferences.a": "hello world",
"preferences.b": 12345
}
// the issue
function getPreference<KeyT extends keyof PreferencesSchema>(key: KeyT): PreferencesSchema[KeyT] {
return data[`preferences.${key}`];
}
// workaround
function workingGetPreference<KeyT extends keyof PreferencesSchema>(key: KeyT): DataSchema[`preferences.${KeyT}`] {
return data[`preferences.${key}`];
}
🙁 Actual behavior
An error occurs:
Type 'DataSchema[`preferences.${KeyT}`]' is not assignable to type 'PreferencesSchema[KeyT]'.
Type 'DataSchema' is missing the following properties from type 'PreferencesSchema': a, b
🙂 Expected behavior
TypeScript should recognize that preferences.a
/preferences.b
is being used as an index, not a
/b
. Therefore it shouldn't matter that DataSchema
is missing a
and b
as properties.