Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Template literal throws errors in some scenarios but not others

As part of a code review a colleague recommended using a type rather than an enum. Whilst making the changes we found an issue neither of us expected.

We’d expect scenario one and two to throw compiler and/or intellisense errors as one of the values does not exist on the type. However, after testing we found only scenario one throws errors whilst scenario two resolves without issue.

This is likely an understanding issue but from everything I’ve read (e.g. Template Literal Types we should be getting errors when a provided value doesn’t exist.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Based on the above, is anyone able to explain why we only see errors on scenario one but not the scenario two?

Scenario One

Example Code

export type FileType = ".png" | ".tif" | ".tiff" | ".jpeg" | ".jpg";

const allowedFileTypes = [".exe"] as Array<FileType>;

Expectation: Compiler error as .exe doesn’t exist

Outcome: Compiler error stating the value doesn’t exist

Scenario Two

Example Code

export type FileType = ".png" | ".tif" | ".tiff" | ".jpeg" | ".jpg";

const allowedFileTypes = [".exe", ".jpeg"] as Array<FileType>;

Expectation: Compiler error as .exe doesn’t exist

Outcome: No compiler errors

Scenario Three

Example Code

export type FileType = ".png" | ".tif" | ".tiff" | ".jpeg" | ".jpg";

const allowedFileTypes = [".png", ".jpeg"] as Array<FileType>;

Expectation: No compiler errors

Outcome: No compiler errors

>Solution :

as Type is a way of saying "This value is this type, even if it doesn’t look like it".

You’re overriding normal type detection.

It’s useful for things like:

const response = await fetch('/some/url');
const data = await response.json();
return data as Foo;

where you know what the shape of the data you are getting back from the HTTP request is, but the compiler has no way of telling that unless you use as to tell it explicitly.


It is dangerous since you can specify a type that doesn’t match the value you actually have (as you’ve discovered).

I have a project underway where I’m using superstruct in order to test the shape of my data inside a typeguard function instead of trusting to as.


You need to specify what is allowed to be assigned to the variable instead:

const allowedFileTypes: Array<FileType> = [".exe", ".jpeg"];
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading