This is the archived version of Roland Weigelt's weblog that ran from 2003 to 2023 at weblogs.asp.net

A Stupid Little TypeScript Mistake

For context: I am a C# developer who uses TypeScript just every now and then. Recently I added a few string constants to an existing TypeScript class. The program compiled just fine, but when I ran the program, the result was different from what I expected.

For a repro scenario, copy the following script code into the Windows clipboard:

class MyStrings {
    public static LoremIpsumDolorSitAmet = "Lorem ipsum dolor sit amet";
    public static ConsecteturAdipiscingElit = "consectetur adipiscing elit";
    public static VestibulumFeugiatLigulaEuOdioPosuereVelTristiqueDiamIaculis = "Vestibulum feugiat ligula eu odio posuere, vel tristique diam iaculis";
    public static FusceUrnaLiberoEfficiturNecTortorSed = "Fusce urna libero, efficitur nec tortor sed";
    public static UllamcorperFaucibusAugueProinUtPurusMetus = "ullamcorper faucibus augue. Proin ut purus metus";
    public static CurabiturAPosuereDiamSedElementumSedNislVitaeMaximus = "Curabitur a posuere diam. Sed elementum sed nisl vitae maximus";
    public static PraesentVitaeEnimVestibulumUltriciesNuncInGravidaSapien = "Praesent vitae enim vestibulum, ultricies nunc in, gravida sapien";
    public static ProinIaculisMiOrciUtRhoncusDuiVenenatisId : "Proin iaculis mi orci, ut rhoncus dui venenatis id";
    public static MorbiSedCongueLigulaSedFinibusNeque : "Morbi sed congue ligula, sed finibus neque";
    public static PellentesqueEuMolestieExIdFermentumEllus : "Pellentesque eu molestie ex, id fermentum tellus";
}

console.log(MyStrings.LoremIpsumDolorSitAmet);
console.log(MyStrings.ConsecteturAdipiscingElit);
console.log(MyStrings.VestibulumFeugiatLigulaEuOdioPosuereVelTristiqueDiamIaculis);
console.log(MyStrings.FusceUrnaLiberoEfficiturNecTortorSed);
console.log(MyStrings.UllamcorperFaucibusAugueProinUtPurusMetus);
console.log(MyStrings.CurabiturAPosuereDiamSedElementumSedNislVitaeMaximus);
console.log(MyStrings.PraesentVitaeEnimVestibulumUltriciesNuncInGravidaSapien);
console.log(MyStrings.ProinIaculisMiOrciUtRhoncusDuiVenenatisId);
console.log(MyStrings.MorbiSedCongueLigulaSedFinibusNeque);
console.log(MyStrings.PellentesqueEuMolestieExIdFermentumEllus);

Now head to the TypeScript Playground at https://www.typescriptlang.org/play, replace the text on the left side with the content of the clipboard and run the script.

This will give you the following output:

It took me a bit until it dawned on me why the last three strings are undefined – can you immediately figure out what the problem is?

A hint: Just before I edited the class, I worked on a couple of JSON files.

4 Comments

  • You have set the type of the last 3 static class fields to a defined literal string. However I would expect that Typescript would have complained that the field is undefined but the literal string type does not allow undefined.
    In other words I believe this:

    public static MorbiSedCongueLigulaSedFinibusNeque : "Morbi sed congue ligula, sed finibus neque";

    ... should bring up a compiler warning.

  • Hi Dalibor,
    a compiler warning would have been helpful ;-)
    To make sure that I did not ignore a warning in the wall of text generated by the real-life build and that the TypeScript playground did not simply swallow the warning, I have just used "tsc" (version 4.3.2) to compile the repro code on the command line. It did not complain.

  • Interesting, it considers these as types? There should be an ESLint rule at least...

  • For me as a C# dev, literal types (https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) are unusual. But I understand where the use case for this language feature is coming from - combined into unions, they can help to make using an existing JavaScript API (with string parameter values like "left", "center","right") safer.