Uncaught Error: Cannot find module ’26sb0′ – Javascript service file not working

In my Vanilla JS project, I want use an external service file to fetch data from an API. When trying to log the data from the API call, I get the error Uncaught Error: Cannot find module ’26sb0′

The files index.html, index.js and apiService.js are in the **src **folder.

I imported the javascript files in the index.html document:

<script type="module" src="index.js" defer></script>
<script type="module" src="apiService.js" defer></script>

I make the API call in the apiService.js file:

const apiUrl = 'https://api.spoonacular.com';

export const fetchData = async(path) => {
    const res = await fetch(`${apiUrl}/${path}`);
    const data = await res.json();
    return data;
};

Finally, I import the fetchData function in my index.js file and make an API call:

import { fetchData } from './apiService';
const testData = await fetchData(`recipes/random?apiKey=xxxxxxxxxxxxxxxxxx`);
console.log(testData);

Bootstrap Tooltips and PopOvers throwing error on createPopper()

I’m trying to setup Bootstrap popovers and I’m getting the following error in the console:

s.createPopper is not a function
    at je._createPopper (tooltip.js:375:19)
    at je.show (tooltip.js:214:25)
    at tooltip.js:509:14

I have initialized the popovers per the docs with:

// Initialize Tooltips
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));

The components are attached to buttons:

<section class="container">
    <div class="display-3 mt-5 m-5 fw-lighter text-uppercase">sponsors</div>
    <div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 align-items-center justify-content-evenly">
      <div id="happy-ifood" class="col sponsor__img rounded-3 border border-info my-3 p-3">
        <img class="w-100 h-100" src="img/food-sponsor.png" alt="Happy Food: food sponsor">
        <button class="btn btn-info learn-more text-capitalize text-white" type="button" data-bs-toggle="popover" data-bs-container="happy-ifood" data-bs-title="Happy iFood" data-bs-content="Happy iFood trucks will be on-site with 8 different cuisine options.">learn more</button>
    </div>
 </div>
</section>

The styling for the surrounding elements are:

.sponsor__img {
  display: block;
  width: 25rem;
  height: 20rem;
  position: relative;
  /* margin: 2rem;
  padding: 1rem; */
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
}
.learn-more {
  height: max-content;
  width: max-content;
  font-size: 1.8rem;
  bottom: 0;
}

The error is occurring at the return value of the _createPopper(tip) function in the tooltip.js file. I would like some direction on what’s happening here. Thanks.

Reusable React-Toastify Component

I’m trying to create a reusable Toast Component.

here is the code: https://codesandbox.io/s/custom-toastify-toast-with-react-component-forked-mu2l9c?file=/src/Toast.js:146-680

On rendering the Toast Component itself [commented below], the toast pops up beautifully.

return (
    <>
      {/* <Toast /> */}   ---> This one works perfectly.
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        name="input"
      />
    </>

However, I am trying to achieve calling of toast using exposed toastMeta . So that the caller can simply type toastMeta.message("please show up..") to get the Toast. Also passing an optional param horizontal and vertical position.

Note: This CustomToast will be a npm package, so the caller has to install this library and import the toastMeta.

export const toastMeta = {
  position: "top-right",
  message: "Error Toast"
};

export const Toast = ({ className, children, ...props }) => {
  return (
    <>
      <ToastContainer {...props}>
        {toast.error(toastMeta.message, {
          position: toastMeta.position,
          autoClose: 3000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
          theme: "colored"
        })}
      </ToastContainer>
    </>
  );
};

Calling toast after every key stroke..

const [input, setInput] = useState("");

  useEffect(() => {
    toastMeta("Error Message..");
  }, [input]);

  return (
    <>
      {/* <Toast /> */}
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        name="input"
      />

Reason for creating a Toast Component:

For version control as its one of the component of the Common Library. The common library has all the UI elements.

Your help is highly appreciated. Thank you in advance.

Unable to validate image using Nodejs Api

I am working with Nodejs and using expressjs framework,Right now i am trying to upload image using Api but
i want two things

1) if image extension is not "jpg,png,gif" then error message should display

Here is my current code

var storage =   multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
 filename: function (req, file, callback) {
     var sizeOf = require('image-size');
        var sizeOf = require('image-size');
        const originalname = file.originalname;
        const fileExt = originalname.split(".").pop();
       const excatName = originalname.split(".").slice(0, -1).join(".");
       console.log("mimetype is " + file.mimetype); // GETTING FILE EXTENSION NAME
       callback(null, excatName + "-" + Date.now().toString() + "." + fileExt);
      },
});
var upload = multer({ storage: storage }).single('userPhoto');
 const uploadavatar = function (req, res) {
    upload(req,res,function(err) {
        if(err) {
            return res.end("Error uploading file." + err);
        }
        res.end("File is uploaded");
    });
};
 

Npm publish is just hung?

I am trying to publish a package that I made. For some reason it is just hung. There is no error or anything. Just a cursor and nothing. I have tried doing an npm login and also npm adduser both have me logged in successfully. So I did npm publish --verbose and here is the output.

PS D:DevelopmentProjectsscrollpropackage> npm publish --verbose
npm verb cli C:Program Filesnodejsnode.exe C:Program Filesnodejsnode_modulesnpmbinnpm-cli.js
npm info using [email protected]
npm info using [email protected]
npm verb title npm publish
npm verb argv "publish" "--loglevel" "verbose"
npm verb logfile logs-max:10 dir:C:UsersWamoAppDataLocalnpm-cache_logs2023-04-18T03_59_42_589Z-
npm verb logfile C:UsersWamoAppDataLocalnpm-cache_logs2023-04-18T03_59_42_589Z-debug-0.log
npm verb publish [ '.' ]

and here is the contents of the log file:

0 verbose cli C:Program Filesnodejsnode.exe C:Program Filesnodejsnode_modulesnpmbinnpm-cli.js
1 info using [email protected]
2 info using [email protected]
3 timing npm:load:whichnode Completed in 1ms
4 timing config:load:defaults Completed in 1ms
5 timing config:load:file:C:Program Filesnodejsnode_modulesnpmnpmrc Completed in 1ms
6 timing config:load:builtin Completed in 1ms
7 timing config:load:cli Completed in 1ms
8 timing config:load:env Completed in 1ms
9 timing config:load:file:D:DevelopmentProjectsscrollpropackage.npmrc Completed in 1ms
10 timing config:load:project Completed in 1ms
11 timing config:load:file:C:UsersWamo.npmrc Completed in 0ms
12 timing config:load:user Completed in 0ms
13 timing config:load:file:C:UsersWamoAppDataRoamingnpmetcnpmrc Completed in 0ms
14 timing config:load:global Completed in 0ms
15 timing config:load:setEnvs Completed in 1ms
16 timing config:load Completed in 6ms
17 timing npm:load:configload Completed in 6ms
18 timing npm:load:mkdirpcache Completed in 0ms
19 timing npm:load:mkdirplogs Completed in 0ms
20 verbose title npm publish
21 verbose argv "publish" "--loglevel" "verbose"
22 timing npm:load:setTitle Completed in 1ms
23 timing config:load:flatten Completed in 2ms
24 timing npm:load:display Completed in 5ms
25 verbose logfile logs-max:10 dir:C:UsersWamoAppDataLocalnpm-cache_logs2023-04-18T03_59_42_589Z-
26 verbose logfile C:UsersWamoAppDataLocalnpm-cache_logs2023-04-18T03_59_42_589Z-debug-0.log
27 timing npm:load:logFile Completed in 4ms
28 timing npm:load:timers Completed in 0ms
29 timing npm:load:configScope Completed in 0ms
30 timing npm:load Completed in 18ms
31 verbose publish [ '.' ]
32 silly logfile start cleaning logs, removing 2 files
33 silly logfile done cleaning log files

I don’t see any errors here. But then there is still just a cursor after that and nothing happens. The batch job doesn’t end it is just hung there forever. You can check the package files out at the repository here Github Repo. So I figured I would try to publish a package that I have already published and it worked fine. So then I tried to publish just a random package that I created real quick and it worked just fine. So there has to be something little that I am missing here causing it to not work. It is a little bit larger package so I let it sit for about an hour and I still just get a black cursor and nothing happens. Any help here would be much appreciated.

I am trying to make an otp submit form. On my computer everything works fine but it gets messed up when using virtual keyboard

This is my layout for otp screen. When I enter the digits of otp one by one the focus has to shift right one box automatically after sometime. This is happening correctly in case of computers but it is not happening in case of virtual keyboards when the site is opened on mobile phones.

OTP screen design

Here is an example of the error I am facing on mobile view. As you can see that rather than having one digit in one box it takes all the input in one box only.

OTP screen on mobile

Here is my JS code for controlling the event :

codes.forEach((code, idx) => {
code.addEventListener('keydown', (e) => {
    if (e.key >= 0 && e.key <= 9) {
        codes[idx].value = '';
    } else if (e.key === 'Backspace') {
        codes[idx].value = '';
        setTimeout(() => codes[idx - 1].focus(), 10);
    } else {
        e.preventDefault();
    }
});

});

Here is my HTML code

<form action="" id="otp-form" method="POST">
                    <div class="code-container flex flex-wrap gap-1 md:gap-2 mx-auto justify-center items-center">
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[0]" required>
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[1]" required>
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[2]" required>
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[3]" required>
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[4]" required>
                        <input type="number" class="code h-9 w-9 sm-micro:w-12 sm-micro:h-12 text-center text-md md:text-2xl text-gray-700 rounded-md md:rounded-lg shadow focus:outline-none focus:border-black focus:ring-transparent focus:shadow-lg font-medium border-2 border-gray-500"
                            placeholder="-" min="0" max="9" name="otp[5]" required>
                    </div>
                    <div class="mt-5 w-full flex justify-center items-center">
                        <button href="" class="mx-auto bg-blue-600 px-3 py-2 rounded-md text-white font-bold">Verify OTP</button>
                    </div>
                </form>

Web Worker written in Typescript does not get built/compiled (using vite) into Javascript

I am using a Web Worker in typescript the following way:

const url = new URL("src/lib/Functions/CalculateRidge.ts", import.meta.url);
const worker = new Worker(url, { type: 'module' })

In development, this work perfectly fine, the worker is loaded from the given url, and the worker executes the function and gives the correct result. But when building, all files get converted to .js except my worker file. Then in deployment (Github Pages) when the same code above is being executed, the url request IS succesful (it finds the file and makes a valid/succesful request for it), but the code fails with the following error message:

“Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of “video/mp2t”. Strict MIME type checking is enforced for module scripts per HTML spec.”

I believe this error comes because a typescript file (a file with .ts extentions) cannot be executed or read, so i believe the error lays in that the Web Worker file is not being compiled/transformed into Javascript.

This is an image of the distribution/build folder:

enter image description here

I use “vite build” to build the project and “npx gh-pages -d dist” to deploy the project to Github Pages. The vite.config.ts file looks like this:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import path from 'path';

// https://vitejs.dev/config/
export default defineConfig({
  base: "/solar-analysis-faroe-island/",
  plugins: [svelte()],
  resolve: {
    alias: {
      src: path.resolve('src/'),
    }
  },
})

tsconfig.node.json looks like this:

{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node"
  },
  "include": ["vite.config.ts"]
}

tsconfig.json looks like this:

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "resolveJsonModule": true,
    "paths": {
      "src/*": [
        "src/*"
      ]
    },
    /**
     * Typecheck JS in `.svelte` and `.js` files by default.
     * Disable checkJs if you'd like to use dynamic types in JS.
     * Note that setting allowJs false does not prevent the use
     * of JS in `.svelte` files.
     */
    "allowJs": true,
    "checkJs": true,
    "isolatedModules": true
  },
  "include": ["src/*.ts","src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

And svelte.config.js looks like this:

import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
  // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
  // for more information about preprocessors
  preprocess: vitePreprocess(),

}

drag an image with the cursor using react

i have a div with a background image and i want to drag the image with the cursor within the bounds on the div, i set the background position to a variable and then added an onmousemove event to the div where i set the variable to the cursor position

const [mousePos, setMousePos] = useState({});
const [imageCenter, setImageCenter] = useState(`center`);

useEffect(() => {
const handleMouseMove = (event) => {
  setMousePos({ x: event.clientX, y: event.clientY });
};

window.addEventListener('mousemove', handleMouseMove);

return () => {
  window.removeEventListener(
    'mousemove',
    handleMouseMove
  );
};
}, []);

the div

<div style={{height:`100%`,width:`100vw`,background:`url(${displayImage}) no-repeat ${imageCenter} / cover`,position:`relative`}} onMouseMove={() => setImageCenter(`${mousePos.x}px ${mousePos.y}px`)
      } onMouseOut={() => setImageCenter(`center`)}>
      </div>

but when i drag the image the cursor is at the top left corner of the image, i want to make it so that focal point of the drag is the cursor position, the image is dragged by the cursor position not by the top left corner, how would i do that and would it be easier to do it using an html inside a

Await doesnt wait till a variable is set in an sync function

I am trying to get dataURI for an image using ApexCharts.exec method, here is my code:

const getDataURI = async() => {

  console.log('leftChartObj', leftChartObj) // gets the data required correctly - essentially an object which is used in the next line; so leftChartID is assigned the value as expected.

  const leftChartID = leftChartObj.props.options.chart.id;

  ApexCharts.exec(leftChartId, 'dataURI' , {scale:1.08}).then(  
  ( async ({imgURI}) => {
     await setSvgLeft(imgURI);          // These methods are inbuilt and I guess async/await isn't needed but I was just trying out.
 
     console.log('svgLeft', svgLeft) // state variable that is set in the above line =
  })
  );

  console.log('method ended', svgLeft) 

}


And this is the output I get:

leftChartObj { 'props': {...}, 'context': {...} , .. } - as expected

method ended null

svgLeft  null

I understand that the code is exiting before the variable is set, then tried async/await. But that didn’t help either.

Also, this function is called upon a button click in the UI, if the click the button for the second time everything works as expected.

Why does the area in the block look different in the mobile and web versions of Telegram? [duplicate]

My problem is that I’m trying to send a table as symbols via telegram bot using the table library for node.js. The table is generated and sent, but it looks different in mobile and web versions of telegram. How can I solve this problem?

— index.ts


import TelegramBot from 'node-telegram-bot-api'

import { table } from 'table'

const token = 'TOKEN'

const bot = new TelegramBot(token, { polling: true })

bot.on('message', msg => {

 const chatId = msg.chat.id

 const data = []

 for (let i = 0; i < 10; i++) {

  const str = i.toString()

  data.push([str, str, str])

 }

 const message = "<pre>" + table(data) + "</pre>"

 bot.sendMessage(chatId, message, { parse_mode: 'HTML' })

})

All the libraries were the latest version.

enter image description here

enter image description here

I tried to use other libraries like markdown-table, ascii-table, and so on.

How to create custom alert dialog box with angular material 15 dialog box

first I created custom dialog module then generate its component and then its service…

files
-custom-dialog
--custom-dialog.component.html
--custom-dialog.component.css
--custom-dialog.component.ts
--custom-dialog.module.ts
--custom-dialog.service.ts

First import mat dialog in module

custom-dialog.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CustomDialogComponent } from './custom-dialog.component';
import { MatDialogModule } from '@angular/material/dialog';


@NgModule({
  declarations: [
    CustomDialogComponent
  ],
  imports: [
    CommonModule,
    MatDialogModule
  ],
  exports: [
    CustomDialogComponent
  ]
})
export class CustomDialogComponent { }

custom-dialog.service.ts

import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { CustomDialogComponent } from './custom-dialog.component';

@Injectable({
  providedIn: 'root'
})
export class CustomDialogService {

  constructor(
    private dialog: MatDialog
  ) { }

  alert() {
    this.dialog.open(DialogComponent);
  }
}

custom-dialog.component.ts

import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

@Component({
  selector: 'app-custom-dialog',
  templateUrl: './custom-dialog.component.html',
  styleUrls: ['./custom-dialog.component.scss']
})
export class CustomDialogComponent {

  constructor(
    public dialogRef: MatDialogRef<CustomDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {}

}

custom-dialog.component.html

<mat-dialog-content>
 alert
</mat-dialog-content>
<mat-dialog-actions align="end">
    <button type="button" mat-button mat-dialog-close>close</button>
</mat-dialog-actions>

this is the code what I write for show alert.

to call this function first i import CustomDialogModule in where i have to call it and import CustomDialogService in component and call alert function which created in service but it shows error in console

Error: Uncaught (in promise): NullInjectorError: R3InjectorError(WebsiteSessionModule)[DialogService -> DialogService -> MatDialog -> MatDialog -> MatDialog]: 
  NullInjectorError: No provider for MatDialog!
NullInjectorError: R3InjectorError(WebsiteSessionModule)[DialogService -> DialogService -> MatDialog -> MatDialog -> MatDialog]: 
  NullInjectorError: No provider for MatDialog!

but when i import matdialogmodule in app.module.ts instead of custom-dialog.module.ts its works fine but i don’t want to call it in app module.

leaflet mouse event on circlemarket not working

function createCamera(camLoc, bear){
    var camera = L.circleMarker(camLoc,{radius: 8, fill: true,});
    camera.addTo(map);
    camera.on('mouseover', function (e) {
        console.log("mouse over");
    })

    // var bearingLineLength= 8000;//M
    // var endpoint =getCameraDestinationPoint(camLoc[0], camLoc[1], bear, bearingLineLength );
    // drawnBearing[i]= L.polyline([camLoc, endpoint], {color: '#098ce4', weight: 2, dashArray: [10, 4]}).addTo(map);
}

the mouseover cannot be called when mouse is hover over the circle created. Can advise on this? Thanks!

Incompatible Type Error When using JSON with Enums in Typescript

The below code is producing a type error which i am not able to solve, Any suggestion would be helpful, I am fairly new to typescript.

1) File name Model.ts which holds below code

export declare namespace player {
 enum status {
   HOLD = "hold".
   PLAYING = "playing",
 }
}

export interface player {
 id? : String;
 playerName? : String;
 joiningDate? : number;
 status : player.status
}

2) Receiving following JSON data via API call

{
    "status" : "success",
    "validations" : null,
    "data" : {
        id? : "scbgfd-23432-kudgba";
        playerName? : 'Jhon Doe';
        joiningDate? : 164952142565;
        status : 'hold'
    }
}

3) Business Logic

export const filterPlayer = (data : Player) : string  => {
    /// Logic For Filtering Player and Returning its ID
}

const player = // Api Call Receiving Above JSON Data //
const filteredPlayer =  filterPlayer(player)  // This line Produce Error

The Error Produced By Above Mentioned Line

Argument Of Type {
    id? : String;
    playerName? : String;
    joiningDate? : number;
    status : player.status
} is not assignable to parameter of type "Player". 
Types of property status are incompatible. 
Type String is not assignable to type "Status | undefined".

What can i pass in the JSON so that the Lint and Test case both doesn’t throw an error !!

TypeError: Cannot read properties of null during testing onSubmit

I’m trying to test whether text in a submit button changes, after the submit button is clicked on.
Once the submit button is clicked, it follows the typical upload image path and gives me errors related to the parent element.

Here is the test:

it("text change within button on load", async () => {
    const user = userEvent.setup();
    const mockFn = jest.fn();
    render(<CreateProfilePhoto handleAddData={mockFn} handleSubmit={mockFn} />);
    const file = new File(["hello"], "hello.png", { type: "image/png" });
    const input = screen.getByTestId("upload-prompt");
    await user.upload(input, file);
    const uploadImage = screen.getByRole("button", { name: /upload image/i });
    await user.click(uploadImage);
    expect(
      screen.getByRole("button", { name: /busy.../i })
    ).toBeInTheDocument();
  });

Here is the error:

   90 |     await user.upload(input, file);
      91 |     const uploadImage = screen.getByRole("button", { name: /upload image/i });
    > 92 |     await user.click(uploadImage);
         |     ^
      93 |     expect(
      94 |       screen.getByRole("button", { name: /busy.../i })
      95 |     ).toBeInTheDocument();

and

Profile Photo Create › text change within button on load

    TypeError: Cannot read properties of null (reading 'uid')

      57 |       const imageRef = ref(
      58 |         storage,
    > 59 |         "profileImage/" + user.uid + "/profilePhoto"
         |                                ^
      60 |       );
      61 |    
      62 |       uploadBytes(imageRef, image)

I tried to add handleSubmit through props but i know that its not passed through props so it won’t make a difference.
What’s causing this error? How do i keep it within the bounds of the unit test?

Ensuring a const (readonly) object’s keys conform to a const (readonly) array of values or type in TypeScript

Let’s say I have an object that I want to make sure its keys conform to another type. I’m creating a dictionary of mapped keys, where on the left I have the original, and on the right, the displayed key. I need this available in both runtime and compile time, so doing this as const objects and arrays seems to make sense?

(Yes, I tried doing this with an array of tuples, but TypeScript is mad at me now).

const allowedKeys = ["cheese_type", "jalapeno_qty", "pepperoni"] as const;

const keyMap = {
   cheese_type:  "Cheese type",
   jalapeno_qty: "Number of jalapeños",
   pepperoni: "Pepperoni",
} as const;

This gives me a type that has all the keys mapped out explicitly:

const keyMap: {
    readonly cheese_type: "Cheese type";
    readonly jalapeno_qty: "Number of jalapeños";
    readonly pepperoni: "Pepperoni";
}

(I can export the types, too)

export const Keys = typeof allowedKeys
export const KeyMap = typeof keyMap

But I also want to protect the keyMap from accidentally misspelling or adding keys that it shouldn’t have, so I want to make it conform to the allowedKeys array.

But if I do that, I can’t figure out how to infer or define the object values as readonly/const properties…

const allowedKeys = ["cheese_type", "jalapeno_qty", "pepperoni"] as const;
type Keys = typeof allowedKeys;

const keyMap: {
  [key in Keys]: string // oh no
} = {
   cheese_type:  "Cheese type",
   jalapeno_qty: "Number of jalapeños",
   pepperoni: "Pepperoni",
} as const;

Is there any way I can do this that doesn’t make me run into crazy cycles like:

const keyMap: {
  [key in Keys]: key in keyMap ? keyMap[key] : never; // haha no
} = {
   cheese_type:  "Cheese type",
   jalapeno_qty: "Number of jalapeños",
   pepperoni: "Pepperoni",
} as const;

(Ultimately, I want to be able to have two sets of keys I can reference…)

export type RawKey = typeof keyMap;
export type DisplayKey = ValueOf<typeof keyMap>;