Why do I need a TypeScript declaration file for a JavaScript library even though type checking works in VSCode in own library?

The following is an AI chat conversation regarding the topic stated in the title.
Depending on the quality of the conversation, modifications may have been made. Modifications may or may not be stated in this page.


Why do I need to generate a declaration file for a javascript library in order to get type hinting in VSCode when I use that library in another project? VSCode can already get types of JS file in the same project. So why does this change when importing from an external library?

Here’s a breakdown of why declaration files are required for type hinting in VSCode when using external JavaScript libraries:

1. JavaScript’s Dynamic Nature:

  • JavaScript is dynamically typed, meaning type information isn’t explicitly included in the code itself. This flexibility makes it harder for editors to infer types accurately, especially for external code.

2. VSCode’s Type Hinting Reliance:

  • VSCode heavily relies on type information for features like:
    • IntelliSense (code completion, suggestions)
    • Hover information
    • Parameter and type checking
    • Refactoring tools

3. Separate Project Scope:

  • When a library is in a separate project, VSCode can’t directly analyze its source code to infer types. Declaration files (.d.ts) bridge this gap.

4. Declaration Files:

  • They describe the types of variables, functions, and classes within a library.
  • They’re written in TypeScript, a superset of JavaScript with explicit typing.
  • VSCode can leverage them for type hinting even in JavaScript projects.

5. Type Acquisition Methods:

  • Automatic: VSCode tries to automatically fetch declaration files for popular libraries.
  • Manual: Install declaration files from DefinitelyTyped (a community repository): npm install --save-dev @types/<library-name>
  • Generating: Compile a library’s TypeScript source code or use tools to create .d.ts files from JSDoc comments.

Key Points:

  • Declaration files are essential for type-aware features in VSCode when using external JavaScript libraries.
  • They make your code more readable, maintainable, and less prone to type-related errors.
  • Consider using TypeScript for new projects to enjoy strong typing and type safety from the start.

The HTMLMediaElement (

The HTMLMediaElement (Mainly <video> and <audio>) contains a “volume” property.
This property is set by the browser and seems to have a default value of max (1.0).
This “volume” property can be modified via JavaScript, by simply set a valid value between 0 and 1.
It seems that it is sometimes altered on videos such as in YouTube adverts.
The reason for this is described in the AI conversation I shared below. To summarize, advert owners seem to have the ability to change the volume.


The following is an AI chat conversation regarding the topic stated in the title.
Depending on the quality of the conversation, modifications may have been made. Modifications may or may not be stated in this page.


There is a “volume” property on HTMLMediaElement elements. It can be modified. When playing a YouTube video, I checked the value, and it was 0.4415704270182424. Is this value the default value? Can this value be changed at a browser or browser extension level? Can this value be changed at an OS level? Why is this valued used, and not a max value of 1?

No, the value you observed (0.4415704270182424) is not the default value for the volume property on HTMLMediaElement elements. The default value is 1.0, which represents the maximum volume.

Here’s a breakdown of your questions:

Can this value be changed at a browser or browser extension level?

  • Yes, the volume property can be changed through both browser settings and browser extensions. Browsers usually have volume controls built-in, and many extensions offer additional functionalities like volume normalization or specific volume adjustments for certain websites.

Can this value be changed at an OS level?

  • Yes, most operating systems have system-wide volume controls that apply to all applications, including web browsers. Adjusting the system volume will also affect the volume of HTML media elements.

Why is this value used, and not a max value of 1?

There are a few reasons why the specific value you encountered might not be 1.0:

  • Initial volume setting: Some websites or video players might have a different initial volume setting than the browser default.
  • User interaction: The user might have previously adjusted the volume using the browser controls, an extension, or the system volume, resulting in the value you observed.
  • Automatic volume adjustments: Certain browser extensions or system settings might automatically adjust the volume based on various factors like ambient noise level or user preferences.

It’s important to note that while the volume property technically allows values between 0 (muted) and 1 (maximum), some browsers or extensions might use a different scale or apply additional logic, potentially leading to non-intuitive values like the one you observed.


The value was that when viewing an advert on YouTube. Was the value that because of being on YouTube, or the advert?

The observed value (0.4415704270182424) for the volume property in your case is likely not directly caused by being on YouTube itself, but rather due to the specific advertisement you were watching or previous user interaction. Here’s why:

  1. YouTube doesn’t automatically adjust volume: While some websites might have their own initial volume settings, YouTube itself doesn’t have a known feature that automatically adjusts the volume for specific content like advertisements.

  2. Advertisers control their content: Advertisements on YouTube are uploaded by individual companies or agencies. These entities have control over the audio levels within their ads, which could explain the specific volume level you observed.

  3. Past user interaction: As mentioned earlier, the volume property could have been previously adjusted through browser controls, extensions, or system settings, impacting the value you saw even during the ad.

Therefore, the specific value you encountered is more likely a combination of:

  • The volume level set within the advertisement itself.
  • Any previous volume adjustments you or your system made.

It’s important to note that while there are no regulations directly mandating specific volume levels for online advertisements, many users find sudden changes in volume disruptive. YouTube itself offers a feature called “Stable volume” that aims to reduce volume fluctuations between videos and ads. However, it’s ultimately left to individual advertisers to be mindful of their ad’s audio levels to create a positive user experience.

Tree shaking ES6 JavaScript code. Does tree-shaken bundle of single named export contain others of that file?

The following is an AI chat conversation regarding the topic stated in the title.
Depending on the quality of the conversation, modifications may have been made. Modifications may or may not be stated in this page.


When tree shaking ES6 JavaScript code, if I import a single named function from a file that exports multiple named functions, will the tree shaken code still contain the other named functions?

No, in most cases, tree shaking will remove the unused named functions from the final code. Here’s how it works:

  1. Static Analysis: Tree shaking tools like Webpack or Rollup analyze the module’s import statements. They create a dependency graph, mapping which exported functions are actually used by other modules.

  2. Unused Code Elimination: If a named function is not imported anywhere, tree shaking removes it from the final bundle. Only the necessary code for used functions is included.

Example:

JavaScript
// math.js
export function add(x, y) { return x + y; }
export function subtract(x, y) { return x - y; }

// main.js
import { add } from './math.js';

console.log(add(2, 3));
  • After tree shaking, subtract will be removed from the final code, as it’s not imported in main.js.

Important Considerations:

  • Tree shaking is most effective with direct named imports: While it generally works with named imports, it might be less effective with default imports or complex module structures.
  • Side Effects: Tree shaking cannot remove functions that have side effects, like modifying global state or accessing external resources, even if they’re not directly used. The bundler assumes they might be necessary for the application to function correctly.

Tips for Effective Tree Shaking:

  • Use named imports whenever possible.
  • Be mindful of side effects in exported functions.
  • Consider using bundler options like sideEffects: false in package.json to provide hints about modules that can be fully tree-shaken.
  • Use tools like Webpack Bundle Analyzer to visualize the generated bundle and identify optimization opportunities.

Research notes regarding converting JSDoc to TypeScript types

A lot of my JS code had been typed with JSDoc comments.
JSDoc comments are very useful for typing JavaScript code, and also have the benefit of allowing inline TypeScript types and importing TypeScript types from ts files. Types can be checked easily in modern editors such as VSCode. For example, the code below, imports from a ts file and types the variable.

/**
* @type {import('tsfile.ts').MyType}
*
const myVariable = 'abc';

It is also possible to declare the type using @typedef to reuse within the file.

/**
* @typedef {import('tsfile.ts').MyType} MyType
*

/*
* @type {MyType}
*/
const myVariable = 'abc';

However, one big issue with JSDoc is that importing it from external libraries seems to not work.
TypeScript types seem to be usable without any processing by just referencing the file such as:

/**
* @typedef {import('my-library'/ts-file-location.ts).MyType} MyType
*/

For JSDoc, generate type declaration files seems to be required.
This is fine, and is expected for JS projects, but it is an extra step that needs to be prepared for all JS projects.

Considering, TypeScript can be imported into JSDoc in the first place, there is really no reason to store type files using JSDoc. The solution is then to isolate types into type only files in ts, and then export each type. This makes it easy to import into JSDoc and into other projects without and processing.

Searching for solutions to convert JSDoc to TypeScript did take my down and long-winding road of issues, that seems to not have been worth the trouble. I have written any significant information in the notes below, but the solution is to just use tsc from TypeScript. See below.

TypeScript tsc

  • Seems to work best. Just need to add exports if necessary and extract from generated file(s).
# Update [SOURCE] below.
# tsc [SOURCE] --declaration --emitDeclarationOnly --allowJs
#
# Notes:
# -- outFile [BUNDLE_DESTINATION] // Works for only some code, so use optionally. https://www.typescriptlang.org/tsconfig/#outFile
# .d.ts file is created in same location with same name before extension.
# To create ts file with exports, SHOULD remove the ".d" part for declaration file, and replace each "type " with "export type ".
# MAY do the same for "interface", but seems like not used (maybe if specifically specified in JSDOC as interface?).
# To prevent replacing wrong code within comments/strings, etc., check that "type" starts at beginning of line.

Notes

ts-migrate

ts-fix

TypeScript codefixes

Other

When the URL of an iframe is changed within the iframe, the iframe element’s “src” attribute does not change. What is the reasoning for this?

I asked Bard AI about why iframes don’t update the src attribute when the content changes, and got a very logical response.

Thinking about it, one obvious point is that the content within the iframe should not leak any data in the page. This is because in the iframe, the content may include something like an OAuth login, or query state. It is possible that the query parameters could contain something like an OAuth code or sensitive search queries, which should definitely not be shared with the parent DOM.

The full response is below.

There are a few reasons why the iframe element’s src attribute does not change when the URL of an iframe is changed within the iframe.

First, it is important to remember that an iframe is a separate document from the parent document. When you change the URL of an iframe within the iframe, you are actually changing the URL of the embedded document, not the iframe element itself.

Second, the src attribute of an iframe element is read-only. This means that once the src attribute is set, it cannot be changed.

Finally, there is a security risk associated with allowing iframes to change their own src attribute. If an iframe were able to change its own src attribute, it could potentially load malicious content from a different domain.

To avoid these problems, if you need to change the URL of an iframe, you must do so from the parent document. You can do this using JavaScript to set the src attribute of the iframe element.

Here is an example of how to change the URL of an iframe using JavaScript:

JavaScript
// Get the iframe element
var iframe = document.getElementById('myIframe');

// Set the src attribute of the iframe element
iframe.src = 'https://new-url.com';

When you set the src attribute of an iframe element using JavaScript, the iframe will be reloaded with the new URL.

It is important to note that you can only change the URL of an iframe if the iframe is from the same domain as the parent document. If the iframe is from a different domain, you will need to use a cross-origin resource sharing (CORS) request to change the URL of the iframe.

How to mark an npm project as for Node.js or for browser or for both?

One issue I have often run into when using npm packages is not supporting the browser.
It is common for even a simple utility package to have a dependency on an npm package and so only work in Node.js. It would be nice if this could be detected quickly, especially automatically.
I asked this question to Bard AI, and got a useful response. The response doesn’t solve the issue for all packages as it requires certain optional properties to be set, but if they are set, then it can be decided what environment support exists.

Is there a common or official way to mark an npm project as for usage of Node.js(not browser), vice-versa, and both?

Yes, there are two ways to mark an npm project as for usage of Node.js (not browser), vice-versa, and both.

  • Using the engines field in the package.json file. This is the official way to specify the runtime environment that a package requires. The engines field is a list of objects, each of which specifies a minimum version of a particular runtime environment. For example, to specify that a package requires Node.js 16 or later, you would add the following to the engines field:
"engines": {
  "node": ">=16"
}
  • Using the browserslist field in the package.json file. This field specifies the browsers that a package supports. If you want to specify that a package is only for Node.js, you would set the browserslist field to an empty array. For example:
"browserslist": []

If you want to specify that a package is for both Node.js and the browser, you would set the browserslist field to a list of browsers that the package supports. For example:

"browserslist": ["last 2 versions", "not ie <= 11"]

The browserslist field is used by the npm command to determine which packages to install when you run npm install. For example, if you have a package that is only for Node.js, and you run npm install, the npm command will only install the packages that are listed in the engines field.

I hope this helps! Let me know if you have any other questions.