/r/typescript

Photograph via snooOG

TypeScript is a language for application-scale JavaScript development.

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

Resources

Language

Discussion

Rules

  1. Your post should be typescript focused This is r/typescript, lets keep it on topic
  2. No general advertising, promoting services/libs with zero TS utility or closed source projects We get it, you people build awesome things, but this isn't r/sideproject, if you're posting a project it needs to be open source, you need to link to the repo and most importantly given that this is r/typescript it should not only be in typescript but be something that contributes to TS utility (Not just a random lib that happens to be written in TS). Also no general spam of other products or software, even if it's free. Exceptions can be made for software that will be exceptionally useful for typescript development and pipelines, but this is at the moderation teams discretion.
  3. Keep self promotion to a minimum. "It's perfectly fine to be a redditor with a website, it's not okay to be a website with a reddit account." - Confucius
  4. No Recruiters. or recruitment posts, we have a sticky for that, still, it's for redditors only, not professional recruiters.

/r/typescript

126,405 Subscribers

4

Who's hiring Typescript developers May

The monthly thread for people to post openings at their companies.

* Please state the job location and include the keywords REMOTE, INTERNS and/or VISA when the corresponding sort of candidate is welcome. When remote work is not an option, include ONSITE.

* Please only post if you personally are part of the hiring company—no recruiting firms or job boards **Please report recruiters or job boards**.

* Only one post per company.

* If it isn't a household name, explain what your company does. Sell it.

* Please add the company email that applications should be sent to, or the companies application web form/job posting (needless to say this should be on the company website, not a third party site).

Commenters: please don't reply to job posts to complain about something. It's off topic here.

Readers: please only email if you are personally interested in the job.

Posting top level comments that aren't job postings, [that's a paddlin](https://i.imgur.com/FxMKfnY.jpg)

0 Comments
2024/05/01
00:00 UTC

2

Can't make generics work properly

I'm trying to implement a generic React component, but I cannot make the props typing work correctly:

import type { ComponentPropsWithoutRef, ElementType } from 'react'

type FooProps<T extends ElementType> = ComponentPropsWithoutRef<T> & { Component: T }

export const Foo = <T extends ElementType = 'a'>(props: FooProps<T>) => {
  const { Component = 'a' as ElementType, ...restProps } = props

  if (Component === 'a') {
    // href is of type "any"
    // How to make "props" be of type ComponentPropsWithoutRef<'a'>?
    const { href } = props

    // Type is properly inferred here:
    return <Component href="" />
  }

  return null
}
5 Comments
2024/04/30
13:42 UTC

5

Can Typescript for React props be terser?

Thanks in advance for any replies. I'm new to Typescript and looking at migrating a JS app, and before I get too deep I want to make sure I really am supposed to write out every prop parameter twice.

E.g. in JS:

function GameList({ userId, sessionId, opt, mode }) {
   ...
}

In TS:

type GameListProps = {
	userId: number,
	sessionId: number,
	opt?: any,
	mode?: string,
};

function GameList({ userId, sessionId, opt, mode }: GameListProps) {
    ...
}

Now when I modify this in the future, I have to update two places and keep them in sync.

I assume there's a good reason I'm currently missing? Like why don't we do this instead?

function GameList({
	userId: number,
	sessionId: number,
	opt?: any,
	mode?: string,
}) {
    ...
}
16 Comments
2024/04/30
03:56 UTC

1

Generate types from imported third party object

Hi, devs! I've been trying to achieve the following goal, but without success. I want to import object from a third party package, then use the keys as type and export the type. I want to build/compile (it is types only package in monorepo) and then use in other packages. Some of the imports are promises. Is there any good approach to do it? Here is quick pseudo code:

import { someObject } from "awesome-package"

type someType = {

  [P in keyof typeof someObject\]: boolean;

}

export { someType }
2 Comments
2024/04/29
23:49 UTC

6

What's the difference between Readonly utility type vs readonly modifier?

It seems the documentation suggests they are practically the same, and it's a matter of developer preference. Is that really so, or are there some rare cases where there's an actual difference?

Readonly<Type> example:

interface Todo {
  title: string;
}
 
const todo: Readonly<Todo> = {
  title: "Delete inactive users",
};
 
todo.title = "Hello";
// Cannot assign to 'title' because it is a read-only property.

readonly Properties example:

interface SomeType {
  readonly prop: string;
}
 
function doSomething(obj: SomeType) {
  // We can read from 'obj.prop'.
  console.log(`prop has the value '${obj.prop}'.`);
 
  // But we can't re-assign it.
  obj.prop = "hello";
// Cannot assign to 'prop' because it is a read-only property.
}

For the sake of search: Readonly utility type has an uppercase (capital) R and is used with angle brackets, whereas readonly modifier is lowercase (all small letters) and used like a keyword.

3 Comments
2024/04/29
23:33 UTC

1

type definitions extracting

i know its a dumb question but i will ask anyway, imagine you can write code like this :

//math.ts
function add(x: number, y: number): number {
  return x + y;
}
//another.ts
import type {add} from './math.ts'
const foo : add 

and ts will extract the type definition from add function to foo const , and whenever i made change in add function thats will reflect with errors or warnings in 'another.ts' file 😅

5 Comments
2024/04/29
21:59 UTC

13

Is there an alternative to Nest?

I am searching for an alternative to Nest.js, but I haven't been able to find any framework that is as comprehensive as Nest. I'm looking for a solution that includes features such as Dependency Injection, ORM, Authentication, and Authorization. Are there any good alternatives to Nest or a suitable stack that meets these requirements that you would recommend?

21 Comments
2024/04/29
20:35 UTC

3

Type inference with env variables.

As of now my project uses a .env file for configuration. The problem with that is I get no type inference in my files and also each time I use a variable I have to write process.env.variable

Extending the processEnv definition of nodeJs namespace works but still I need to rewrite process.env.variable each time

I was wondering if there is a way to just use a variable like env.variable and also get all the typescript features like type inference and intellisense.

22 Comments
2024/04/29
19:06 UTC

0

Need help with Typescript, React, React Query [Paid]

Hey all,

I am working on a task in my current organization and have been thrust into the world of TS, React Query and React. I just started to wrap my head around the SDK but do not have the time to understand the tech stack and implement the feature.

I am looking to seek some help online, and preferably someone who can help me in the next 16-20 hrs of me putting this post out.

This is an extremely tiny task but you will be paid for it. Ideally, you could also help me understand few things regarding the same.

Please shoot me a DM/Chat and will connect with you.

Thanks

0 Comments
2024/04/29
18:39 UTC

32

Knowing what throws and what doesn't: my biggest qualm current state of the JS ecosystem, and TypeScript can help

I'd like to start off by saying this isn't a TypeScript problem, but it can be a TypeScript solution. I'm hoping to find like-minded people who feel the same way about type safety. Currently, it is rather difficult to know exactly what DOM APIs might throw and which ones might not. It would be really nice to have a kind of error map, or at least see in the typescript types what function would call what error (JSDoc "@throws"). I opened a TS feature request. This would allow library developers to easily build off of official error maps, enforcing type safety.

Example: did you know that document.querySelector will throw an exception for invalid syntax? You might think it would just return null or undefined. It doesn't. I patched a bug in a library a while back because they used querySelector and assumed it wouldn't throw. But why would one think it would throw in the first place? It's not like it tells you that! And where do you find this information? You have to go to MDN or something similar. I don't believe any single rockstar developer can have the whole DOM in their head and know which functions throw. And it's unrealistic to be checking constantly to see if simple APIs like querySelector might throw. There are bound to be mistakes, and I'm sure those mistakes have already propagated largely in the wild web world.

So the solution for me is either:

A) have "@throws" be in the type description (hovering over the function tells you if it may throw, and what type it may throw)

or

B) generate error maps so that developers can create libraries that leverage these, creating proxies that can transform function calls into consumables like (neverthrow)[https://github.com/supermacro/neverthrow], forcing error handling and facilitating a high standard of type safety.

I'll say it again: this isn't a TypeScript problem nor TypeScript's responsibility to fix. But it is a problem, and someone needs to do something about it! And it helps when that someone is official and devs can rely on them to stay up to date.

24 Comments
2024/04/29
13:21 UTC

3

How to use 'this' keyword in a conditional required in a Mongoose schema with TypeScript?

Following is the working JS code which I'm now trying to migrate to TS. While defining spotifyData, I used this keyword as you can see down below, to set a required condition depending on the boolean isSpotifyConnected.

I've tried using functions instead of using this directly but then it gives other errors or maybe I'm not doing that right. I tried looking into the documentation and that was hard to understand for me. I need two things, a solution for this particular problem and most importantly, how can I understand what's going on here. Can someone suggest some resources?

import mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    isSpotifyConnected: {
        type: Boolean,
        default: false,
        required: true
    },
    spotifyData: {
        type: {
            access_token:{
                type: String,
                required: this.isSpotifyConnected ? true : undefined
            },
            refresh_token:{
                type: String,
                required: this.isSpotifyConnected ? true : undefined
            },
            expires_in:{
                type: Number,
                required: this.isSpotifyConnected ? true : undefined
            },
            expiry_time:{
                type: Number,
                required: this.isSpotifyConnected ? true : undefined
            }
        },
        default : {}
    }
});

const User = mongoose.model('User', userSchema);
export default User;
2 Comments
2024/04/29
09:20 UTC

5

Add type annotation to import

I remember seeing an import (roughly) like this one

import json from './json' as Type.

But I can't find any docs for it

Is there something like this in TS?

Thank you

2 Comments
2024/04/29
07:08 UTC

3

Auto generated type declarations not detected when using path aliases

I want to use typed-scss-modules with module path aliases. I have configured it the tool to put the generated tyoe definitions in the "__generated__" directory. I have followed all their steps. Now I do not get safety if I import the styles using

import styles from "@/styles/Layout.module.scss";

But it works when I use

import styles from "../../styles/Layout.module.scss";

I have the following set in the tsconfig.json

"rootDirs": [".", "__generated__"],
"baseUrl": "src/",
"paths": {
   "@/styles/*": ["styles/*"]
 }

How do I get the auto generated type definitions to work when using path alias?

2 Comments
2024/04/28
22:00 UTC

13

Real end-to-end type-safety with Expressjs

TLDR: Check out my new end-to-end type adapter for Express.js: express-typed

express-typed-gif

I’ve always appreciated the simplicity of Express, but it was created back in 2009, long before TypeScript emerged in 2014. Consequently, type safety wasn’t built into the framework from the start.

While alternatives like trpc exist, they often come bundled with peculiar adapters specific to trpc, not always seamlessly fitting into other setups.

Another option ts-rest and zodios, but they require upfront type definitions imported into both backend and frontend. This approach can be tedious, especially when dealing with dynamic backend types, such as those in Prisma ORM.

When confronted with these challenges in my recent project, I decided to build a custom type adapter for Express.js Router. This solution relies heavily on type declarations, wrapped in a tiny runtime wrapper around Express.Router, that enables type inference (as TypeScript inference primarily operates declaratively: during assignment and return, while Express.Router routes are declared imperatively)

This library was successfully deployed in production with my latest project, and the results were so impressive that I couldn’t resist extracting the type adapter into a separate library to share with you all.

Check out the GitHub repo for more details, and please share any suggestions or issues you encounter!

1 Comment
2024/04/27
18:54 UTC

14

Returning -1 or null for the bad state of a function that returns a number otherwise?

We've of course seen both. indexOf returning -1 when the item isn't found, and other instances where null is returned. I see some advantages of null though. Namely that the call-site with typescript will have to check it has been handled more explicitly whereas with -1 I think it may be more error prone from a usage perspective. What do you think? What's the best practice?

36 Comments
2024/04/27
13:55 UTC

2

Having issue with typescript and jest in a laravel project. Can someone help me fix this/understand?

EDIT: This problem is fixed. See solution here:

'Cannot find module ... or its corresponding type declarations' vscode error and other 'absolute' import errors when setting up Jest in Laravel + React (typescript) project with vite bundler #211555

I have installed jest with react testing library in my laravel project. After countless hours of figuring out how to set it up, I am encountering this issue:

Cannot find module '@/Components/Checkbox' or its corresponding type declarations

Here is the code segment where the error is occuring:

import { render } from '@testing-library/react';
import React from 'react';

import CheckBox from '@/Components/Checkbox'; //error

describe('Checkbox', () => {
  it('should work as expected', () => {
    render(<CheckBox />);
  });
});
  • tsconfig file

{
  "compilerOptions": { 
    "allowJs": true, 
    "module": "ESNext", 
    "moduleResolution": "bundler", 
    "jsx": "react-jsx", 
    "strict": true, 
    "isolatedModules": true, 
    "target": "ESNext", 
    "esModuleInterop": true, 
    "forceConsistentCasingInFileNames": true, 
    "noEmit": true, 
    "paths": { 
      "@/": ["./resources/js/"],
      "ziggy-js": ["./vendor/tightenco/ziggy"] 
    }
   }, 
  "include": ["resources/js//*.ts", "resources/js//.tsx", "resources/js/**/.d.ts"] 
}
  • jestt

const {pathsToModuleNameMapper } = require('ts-jest'); 
const { compilerOptions } = require('./tsconfig')

/** u/type {import('ts-jest').JestConfigWithTsJest} */ 

module.exports = { 
  preset: 'ts-jest', 
  moduleNameMapper: {  
    ...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/' }),    
    
    // mocking assests and styling   
    '^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':     '<rootDir>/tests/resources/mocks/fileMock.ts',
    '^.+\\.(css|less|scss|sass)$': '<rootDir>/tests/resources/mocks/styleMock.ts',   
    
    /* mock models and services folder */   
    '(assets|models|services)': '<rootDir>/tests/resources/mocks/fileMock.ts', }, 
  },
  // to obtain access to the matchers. 
  // setupFilesAfterEnv: ['./tests/resources/setupTests.ts'],  

  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 
  modulePaths: ['<rootDir>'], 
  testEnvironment: 'jsdom',
};

Here is the file structure:

Frontend components are in `resources/js` and tests are inside `tests/resources`

I looked through countless forums and I am not able to fix this...

13 Comments
2024/04/27
13:19 UTC

1

Can't build my app for production

I'm using tsc as my compiler, when I build my express project with NODE_ENV set to development everything builds fine, as it should.

However, when I set it to production tsc build fails, with error about missing type definitions. For example, @types/cors or @types/express. I understand why they are missing. It's because node install doesn't install dev dependencies when NODE_ENV is set to production, as it should.

Then how am I supposed to build my project for production if tsc build expects dev dependencies? Should I just use NODE_ENV=development? Is there a problem with my configuration? What am I missing?

My start script:

"start": "npx tsc && node dist/index.js",

My tsconfig.json:

https://pastebin.com/0ZtkBPHz

4 Comments
2024/04/27
10:29 UTC

4

How to define a return type that is an array of values of a key of an object?

I'm getting into TypeScript and I'm stumped by this puzzle.

To explain what I'm trying to do:

  1. I have interface ProductObject
  2. I want to write a function that receives an array of productObjects, and a key. The function returns all unique values for that key found in the array of objects

How do I specify the return type of this function?

The product object:

interface ProductObject {
    att1: att1Values,
    att2: att2Values,
    //...
}

Where att1Values = type "valid value 1" | "valid value 2" // | ...

And the function would look like this:

function uniqueVals(objects: ProductObject[], attribute: keyof ProductObject){
    const allVals = objects.map(o => o[attribute])
    return [... new Set(allVals)]
}
12 Comments
2024/04/27
08:58 UTC

7

Output all TypeScript files to a JavaScript file without import/export

I've tried esbuild, deno, rollup, and, of course, tsc.

My goal is to compile all of my TypeScript files into a single JavaScript file so import/export isn't present. The closest result was from these compiler options:

{
  "compilerOptions": {
    "target": "es5",
    "module": "System", // or "AMD"
    "outFile": "transpiled-code/clasp.js",
    "rootDir": "./",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

This does output a single file but the platform I deploy my code to cannot interpret the results from "module": "System" or "module: "AMD".

Has anyone dealt with this before?

20 Comments
2024/04/26
22:04 UTC

1

Generic function to merge 2 types with a common key

Hello,

Basically I'm trying to achieve a SQL inner-join between 2 arrays of types that share a common key.
After a lot of tries and googling, I have to admit this is beyond my knowledge, here's how far I got:

  public merge<Key extends string | number | symbol,
               Value,
               Base extends { [key in Key]: Value },
               Type1 extends Base,
               Type2 extends Base
  >(
    array1: Type1[],
    array2: Type2[],
    key: Key
  ): (Type1 & Type2)[] {
      const merged = array1.map((item1) => {
        const match = array2.find((item2) => item2[key] == item1[key]);
        if (match) {
          return { ...item1, ...match };
        } else {
          return { ...(<Type1>{}), ...(<Type2>{}) };
        }
      });
      return merged;
  }

The compiler complains that item2[key] == item1[key] is not possible because the types don't overlap, but they both extend Base which contains the same key (atleast I'm hoping it would)

Can you help me with that ? Much appreciated :)

PS: Sorry, this is the first time I post code here. I don't know how to enable syntax highlighting, feel free to guide me !
PS2: I know that the complexity of this algorithm can be improved from n*n to n*log(n) and I will do that obviously, after I fixed the compiling.

4 Comments
2024/04/26
07:52 UTC

3

Review Request: Which one is better and why?

Out of these following two pieces of code, which one would you prefer to make part of your code base and why?

A: uses enum

type CompareResult = -1 | 0 | 1;

enum CompareResultOptions {
    Asc = 1 as CompareResult,
    Same = 0 as CompareResult,
    Desc = -1 as CompareResult
};

function compareNumbersAscending(a: number, b: number): CompareResultOptions {
  if(a > b) {
    return CompareResultOptions.Asc;
  } else if(a === b) {
    return CompareResultOptions.Same;
  } else {
    return CompareResultOptions.Desc;
  }
}

var a = Array.from({length: 100}, _ => Math.floor(Math.random() * 100))

console.log({a});
console.log({sorted: a.sort(compareNumbersAscending)});

I guess the names Asc, Desc, and Same are not good, what do you suggest?

B without enum

type CompareResult = -1 | 0 | 1;

function compareNumbersAscending(a: number, b: number): CompareResult {
  if(a > b) {
    return 1;
  } else if(a === b) {
    return 0;
  } else {
    return -1;
  }
}

var a = Array.from({length: 100}, _ => Math.floor(Math.random() * 100))

console.log({a});
console.log({sorted: a.sort(compareNumbersAscending)});
27 Comments
2024/04/26
04:27 UTC

2

Apparently Typescript congrats you for finding work-in-progress articles

I came across this page and found this at the top:

This page is a work in progress, congrats on finding it!

I found it hilarious and wanted to share.

Have a nice day!

1 Comment
2024/04/25
18:48 UTC

3

Type narrowing with union types

Hi all,

I have an issue with type narrowing when using union types. I can break down the problem to this simple example:

type OneOfUnion<T, K extends keyof T, V extends T[K]> = T extends { [key in K]: V } ? T : never;

type Animal = {type: 'CAT', livesLeft: number} | {type: 'DOG', name: string}

// Works - type must be CAT and livesLeft is recognized
const cat: OneOfUnion<Animal, 'type', 'CAT'> = {
  type: 'CAT',
  livesLeft: 7
}


// Fails - animal is not recognized as CAT
function logAnimalDetails<T extends 'CAT' | 'DOG'>(
    animal: OneOfUnion<Animal, 'type', T>,
  ) {
    if (animal.type === 'CAT') {
      // Error here
      console.log(`Cat has ${animal.livesLeft} lives left`)
    }
  }

I don't quite understand why in the function the type is not recognized. Thank you for pointing me to the right direction :)

For context, what I try to achieve is to assert to my function that two passed arguments share the same discriminator. Something like this:

type OneOfUnion<T, K extends keyof T, V extends T[K]> = T extends { [key in K]: V } ? T : never;

type Animal = {type: 'CAT', livesLeft: number} | {type: 'DOG', name: string}

type Owner = {type: 'CAT', costsForCatfood: number} | {type: 'DOG', costsForDogFood: number}


export function logAnimalDetails<T extends 'CAT' | 'DOG'>(
    animal: OneOfUnion<Animal, 'type', T>,
    owner: OneOfUnion<Owner, 'type', T>
  ) {
    if (animal.type === 'CAT') {
      // Errors since owner is not narrowed correctly 
      console.log(`Owner spent ${owner.costsForCatfood} for food`)
    }
  }

Thank you :)

16 Comments
2024/04/25
11:44 UTC

1

Adding arbitrary attributes to object using spread operator

Why is it possible to add arbitrary attributes to an object? This should throw a Typescript error in my opinion.

type Params = {
    limit: number;
}

// Does not work
const params: Params = {
    limit: 20,
    q: "john"
}

// Does work
const spreadParams: Params = {
    limit: 20,
    ...({ q: "john" })
};

console.log(spreadParams.q);
// 'john'

https://www.typescriptlang.org/play/?ssl=18&ssc=10&pln=1&pc=1#code/C4TwDgpgBACghgJzgWwM5QLxQN4CgoFQA2AlsicAFxQB2ArsgEYQIDcuAvrrgPQ9QARAPYR0NIcCgB3IQgDWuAMZCaqSWEQpU1eEjSYc+QqXJUoAJgAMAGiMEAjtQBEAKyEALGk87c+gkegy8koqalCoYAgQcAAmulo6mvpYeITEZBTUVrZpAHT5ABTYUI5Qrh5eUBwAlJzsIapCRBC5REIA5gURUbHxaLn21ex+AORuniO4QA

4 Comments
2024/04/25
10:00 UTC

34

Typed-xlsx | Feature-rich Type-safe Excel Reporting

Hey r/typescript!

I've recently developed a library called typed-xlsx which aims to make exporting data to Excel files (xls/xlsx) more straightforward while maintaining strong type safety and an excellent developer experience.

The library wraps around SheetJs but provides a more accessible, high-level API that simplifies many common tasks and enhances features. Key Features Include:

  • Type-safe Schema Builder: Design spreadsheet schemas with enhanced reliability.

  • Type-safe Data Serialization & Transformation: Ensure data integrity throughout your workflow.

  • Shared Type-safe Custom Value Pre-processors: Use shared pre-processors for consistent value transformations across your spreadsheets.

  • Column Summary: Auto-insert computed summaries for columns to facilitate data analysis.

  • Complex Row Structures with Auto-Merging: Simplify the creation of complex layouts with automatic row merging and styling.

  • Easy Default Values Management: Effortlessly manage default values to present your data as intended.

  • Dynamic Column Selection: Choose which columns to include dynamically when building your tables.

  • Dynamic Column Mapping with Type-safe Context: Dynamically map columns in a type-safe manner.

  • Dynamic Cell Styling/Formatting: Apply custom styling and formatting to cells on a per-row basis.

  • Multi-sheet Support: Create spreadsheets that contain multiple sheets for better data organization.

  • Multiple Tables Per Sheet Support: Easily manage multiple tables within a single sheet.

  • Linear or Grid-like Layout for Sheets with Multiple Tables: Choose between linear or grid layouts for sheets that contain multiple tables.

For a comprehensive demonstration of all the capabilities and the API, check out the live demo on the documentation homepage.

This project is open-source, and you can find the repository and detailed documentation here:ed-xlsx on GitHub

I built typed-xlsx to address the complexities and time-consuming aspects of Excel report generation in TypeScript, focusing on speeding up development without sacrificing flexibility or power. I

would love your feedback on the library! Whether it's a feature request, bug report, or general observations, your input would be invaluable to help improve typed-xlsx. Please feel free to contribute to the repo or drop a comment here.

Thank you for checking it out!

8 Comments
2024/04/25
02:01 UTC

5

How to type JS using querySelectorAll or getElementsByClassName

Context:

So I created a VERY basic lightbox to pop out images when they are clicked. My page structure is a div with the ID "popup" with a img tag with the id "popupimg" inside, and then the rest of the page has some images with the class "popout".

Problem:

In the script for all this I can't get typescript to correctly type my "images" const. I am trying to get "images" to be a list of all the images with class popout, And if I leave it untyped it works well and good until I try to run my forEach function where the val "img" is typed as a element and not a HTMLelement and so has no style attribute. And every way I try to type the images component gives me other errors.

My attempt:
I found this in the type script handbook it shows an example of "querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;" but I couldn't figure out how to use that in my code. If I try to use HTMLCollectionOf<HTMLImageElement> for my "images" variable I get "Property 'namedItem' is missing in type 'NodeListOf<Element>' but required in type 'HTMLCollectionOf<HTMLImageElement>" and I have no idea what that means.

<script>
  function addPopout() {
    const images = document.querySelectorAll("img.popout");
    const popup = document.getElementById("popup");
    const popupimg = document.getElementById("popupimg") as HTMLImageElement;
    if (!popupimg.src || !popup) {
      throw new Error("The element popup or popupimg wasn't found");
    } else {
      images.forEach((img: any) => {
        img.style.cursor = "zoom-in";
        img.addEventListener("click", () => {
          popup.classList.toggle("hidden");
          popup.classList.toggle("flex");
          popupimg.src = img.getAttribute("src");
        });
      });
      popup.onclick = () => {
        popup.classList.toggle("flex");
        popup.classList.toggle("hidden");
      };
    }
  }
  window.addEventListener("load", function () {
    addPopout();
  });
</script>
<script>
  // add mobile support for touch
  function addPopout() {
    const images = document.querySelectorAll("img.popout");
    const popup = document.getElementById("popup");
    const popupimg = document.getElementById("popupimg") as HTMLImageElement;
    if (!popupimg.src || !popup) {
      throw new Error("The element popup or popupimg wasn't found");
    } else {
      images.forEach((img: any) => {
        img.style.cursor = "zoom-in";
        img.addEventListener("click", () => {
          popup.classList.toggle("hidden");
          popup.classList.toggle("flex");
          popupimg.src = img.getAttribute("src");
        });
      });
      popup.onclick = () => {
        popup.classList.toggle("flex");
        popup.classList.toggle("hidden");
      };
    }
  }
  window.addEventListener("load", function () {
    addPopout();
  });
</script>

Thanks for taking the time to read through this, and feedback is appreciated.

11 Comments
2024/04/24
20:40 UTC

0

Does Using OOP in JavaScript Make Sense, or Should I Just Switch to TypeScript?

I've been learning OOP in JavaScript and find the reliance on prototypes and class syntax, particularly for private properties, to be clunky and awkward. I expected a system more similar to Java's, and now I'm wondering if JavaScript's OOP peculiarities are why TypeScript was developed. Is JavaScript commonly used for OOP, or is TypeScript a better alternative for those looking for a robust, clean OOP experience? What are your thoughts and experiences?

51 Comments
2024/04/24
17:16 UTC

Back To Top