Is it possible for an uninitialized field of a non-null literal string type to remain undefined even with strict null checks in

It seems that there might be a bug in Typescript regarding the behavior described below. I have submitted an issue on GitHub to address this problem, and you can find it at this link. The code example provided in that issue explains the situation more clearly than the code snippet presented here.


Let's examine the code in the file

undefined-literal-string-field.ts
:

class Foo {
  public foo: 'foo';
}

const foo = new Foo();

console.log('Foo ', foo.foo);

Notice how the property Foo.foo has a literal string type, but it does not include undefined. This means the type is strictly just 'foo', without allowing 'foo' | undefined.

In TypeScript 2.2, this code actually compiles with the flag --strictNullChecks:

$ node_modules/.bin/tsc --version
Version 2.2.2    
$ node_modules/.bin/tsc --strictNullChecks undefined-literal-string-field.ts

However, when executed, the field is undefined:

$ node undefined-literal-string-field.js
Foo  undefined

This inconsistency arises because the property remains uninitialized in the resulting JavaScript code:

var Foo = (function () {
    function Foo() {
    }
    return Foo;
}());
var foo = new Foo();
console.log('Foo ', foo.foo);

I may have misinterpreted the implications of --strictNullChecks, but as far as I understand, this flag should prevent undefined values unless explicitly allowed through union types like 'foo' | undefined. However, that's not what's happening in this case.

Why does the compiler permit accessing an uninitialized field in this scenario where its type does not allow the value undefined? Doesn't this pose a potential unsoundness?

Furthermore, considering that the type of foo only permits a single value, shouldn't the compiler initialize it with that one valid value automatically?

What am I overlooking here?

Answer №1

It seems that, in the code you provided, the foo field is not initialized. The compiler does not generate an error in the console.log line because it recognizes the presence of the Foo class and assumes the field exists (regardless of whether it has been initialized or not).

As for the question of why the compiler doesn't automatically initialize the field, the answer is quite straightforward. The foo: 'foo' declaration serves as a type definition only. It is up to the programmer to purposefully assign a proper value to the field in the code.

If you would like the foo field to have a default value upon initialization, you can modify the class as follows:

class Foo {
    public foo: 'foo' = 'foo';
}

With this adjustment, the field should be properly initialized with the default value.

Answer №2

Because you have initialized the object

const bar = new Bar();

When you are utilizing the code snippet below

class Bar {
  
  public bar: 'bar';

}
let bar: 'bar';

console.log('Bar ', bar.bar);

This will result in

 error TS2454: Variable 'bar' is used before being assigned.

The assignment operator is missing and should be added as follows

public bar = 'bar';

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using a function as a parameter in Typescript: Anticipated no arguments, received 1.ts

I'm encountering an issue when trying to pass the doSomething function into performAction. The error message I'm receiving is Expected 0 arguments, but got 1 interface SomeInterface { name: string, id: string } function doSomethingFunction( ...

Error: *** is not a valid function within a React element

I am encountering an issue while attempting to call a function of an object passed as an argument in a React component's constructor. The error message I receive is: Uncaught TypeError: _this.layout.getWbsLayout is not a function at new Wbs (Wbs. ...

What is the proper way to utilize e.key and e.target.value in TypeScript when coding with React?

I'm struggling to get e.key and e.target.value working with the following code: const handleInputKeyPress = (e: React.KeyboardEvent<HTMLInputElement> ) => { if(e.key ==='Enter') { dfTextQuery(e.target.value) } }; Why is & ...

Fastify Schema Failing to Validate Incoming Requests

Currently, our backend setup involves using Node.js and the Fastify framework. We have implemented a schema in satisfy to validate user input. Below is the schema defined in schema.ts: export const profileSchema = { type: 'object', properti ...

Exploring the Material Drawer functionality within an Angular application

I'm having trouble integrating the Material Drawer component into my Angular app. Despite following the instructions on https://material.io/develop/web/components/drawers/, it's not rendering properly. Could someone please provide a detailed, s ...

The Next.js app's API router has the ability to parse the incoming request body for post requests, however, it does not have the

In the process of developing an API using the next.js app router, I encountered an issue. Specifically, I was successful in parsing the data with const res = await request.json() when the HTTP request type was set to post. However, I am facing difficulties ...

Issue with the code: Only arrays and iterable objects are permitted in Angular 7

Trying to display some JSON data, but encountering the following error: Error Message: Error trying to diff 'Leanne Graham'. Only arrays and iterables are allowed Below is the code snippet: The Data {id: 1, name: "Leanne Graham"} app.compone ...

Is the user's permission to access the Clipboard being granted?

Is there a way to verify if the user has allowed clipboard read permission using JavaScript? I want to retrieve a boolean value that reflects the current status of clipboard permissions. ...

Encountering the error message "express.default is not a function" while attempting to start the node server within a container

Whenever I try to start my node server in a remote container, I keep encountering an error stating "express.default is not a function." Can anyone help me figure this out? Here's the content of my main.ts file: import * as express from 'express& ...

Expanding the current @types type definition to encompass additional properties that are currently absent

Currently, I am utilizing the most recent @types for leaflet in my project (v1.2.5), however, they do not align with the latest version of leaflet (1.3.x). Specifically, their LayerGroup interface lacks a setZIndex property which I need to include by exte ...

Executing functions in Vue TypeScript during initialization, creation, or mounting stages

Just a few hours ago, I kicked off my Vue TypeScript project. I've successfully configured eslint and tslint rules to format the code as desired, which has left me quite pleased. Now, I'm curious about how to utilize the created/mounted lifecycl ...

Firestore data displaying as null values

Recently, I encountered CORS errors while polling the weather every 30 seconds in my program. Upon investigating, I discovered that the city and country were being interpreted as undefined. To fetch user data from my users' table, I utilize an Axios ...

Tips for effectively utilizing typescript interface with the OR operator

I'm a beginner when it comes to TypeScript. I have the following code snippet that I am working on: interface InitialData { active: boolean; status: boolean; } interface Item { id: number; name: string; Data: InitialData; } interface Main ...

Delete the option "x" from the kendo combobox

Is there a way to eliminate or hide the clear ("x") action from a Kendo combobox using TypeScript? I have attempted to find a solution through SCSS/CSS, but I have not been successful. Alternatively, I would be fine with preventing the event triggered by ...

Creating a custom string subtype in TypeScript

I am currently working on developing a game called Risk using TypeScript and React hooks. This game is played on a map, so my first step was to design a MapEditor. The state of the Map Editor is as follows: export interface IMapEditorState { mousePos: ...

Achieving selective exclusion of specific keys/values while iterating through an array and rendering them on a table using Angular

Currently facing a hurdle and seeking advice I am developing an angular application that fetches data from an API and presents it on the page The service I am utilizing is named "Api Service" which uses HTTPClient to make API calls apiservice.service.ts ...

"Error TS2339: The property specified does not exist within type definition", located on the input field

When a user clicks a specific button, I need an input field to be focused with its text value selected entirely to allow users to replace the entire value while typing. This is the markup for the input field: <input type="text" id="descriptionField" c ...

Tips for resolving the TypeScript error related to the global object in Node.js

I am currently working on a project following the steps outlined in this guide https://vercel.com/guides/nextjs-prisma-postgres to develop a full stack application. However, I have encountered an error with TypeScript in the code snippet below: import { Pr ...

The InAppPurchase Plugin in Cordova is throwing the error message "Encountered an error: Cannot access the 'getProducts' property as it is undefined."

Currently, I am utilizing the cordova in-app-purchase plugin for my application. However, I am encountering an error that reads "ERROR TypeError: Cannot read property 'getProducts' of undefined" The .ts file appears as follows: window['plu ...

Add the list of information during the looping process (map)

I am currently facing a challenge where I need to update my data during the iteration and send the results to an API call. The API Call expects a request with data structured in the following format: { list: [{ id: "1", name: "Hello" ...