TypeScript
TypeScript copied to clipboard
Generic types extending Record<Uppercase<string>, ...> ignore the Uppercase utility
🔎 Search Terms
Record<Uppercase
🕗 Version & Regression Information
I tested the following snippet on the playground with all versions starting from 4.9.5 and the behaviour was the same. For all the previous versions down to 4.1 (when Uppercase was introduced) the behaviour was different but the errors seem unrelated.
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.6.3#code/C4TwDgpgBAqmkCcDGBDAzhAShJB7BAJlALxTZ6EA8ciqGlawCAlgHYDmAfADRQCurANatcAd1acA3AChpAMwFJgzXKyhzcuSgBUoEAB7AIrAmljwIydFhz4CnABQAjFAgBcUbQEooAb2lQUAgQwHwIai4IMgC+sgD0cVDAABbMZmjJuHwANkQpCGJQKGqWBQjSeKyMUBlZuQBiKMzZJOqaDv6BGrgeAESRvdzS0V4yspXVck3ZaADqzCkAyijKaHLMEGak3R0BbT1Q-a6DwzUraeub5rTW5Haj46rVC7P4glv7u4H1API-fQMhiMxhNgFAXm85gtkstVpc0NpNK0dp0oL9-odAac0Oc1hszDRLHQbBQCA9pAkoKJkitwXIqdACKoAORgvgYcFgthFKDsYyWZhIdSKZSqAD88hFKjUoEgBHq7UiHkJVgwd0IPlRwVC4SgkRi8USKWgsugokhFSeXOAjWaH1N8vaqO6AOOQNGQA
💻 Code
type UppercaseRecord = Record<Uppercase<string>, unknown>;
function foo<T extends UppercaseRecord>(bar: T) {
return bar;
}
// this should throw an error
const shouldFail = foo({
foo: "bar",
});
const failsWithSatisfies = foo({
foo: "bar",
} satisfies UppercaseRecord);
const itWorks = foo({
FOO: "bar",
});
const itWorksWithSatisfiesToo = foo({
FOO: "bar",
} satisfies UppercaseRecord);
// what if we don't use it in a generic function?
function typedFoo(bar: UppercaseRecord) {
return bar;
}
const itFails = typedFoo({
foo: "bar",
});
🙁 Actual behavior
Passing a record with lowercase properties on foo does not throw an error.
🙂 Expected behavior
Passing a record with lowercase properties on foo should throw an error.
Additional information about the issue
Generic types extending Uppercase<...> seem to work properly.
function foo<T extends Uppercase<string>>(bar: T) {
return bar;
}
foo("FOO");
// this throws an error
foo("foo");