typescript

browser file access

import { saveAs } from "file-saver";

export default () => {
  const fileUpload = useRef<HTMLInputElement>(null);

  const exportQuestions = () => {
    const fileName = "questions.json";
    const fileToSave = new Blob([JSON.stringify(questions, null, 4)], {
      type: "application/json",
    });
    saveAs(fileToSave, fileName);
  };

  const importQuestions = () => {
    if (null !== fileUpload.current) {
      const file = fileUpload.current.files![0];
      if (file) {
        var reader = new FileReader();
        reader.readAsText(file, "UTF-8");
        reader.onload = (evt: ProgressEvent<FileReader>) => {
          if (evt.target && typeof evt.target.result === "string") {
            console.log(JSON.parse(evt.target.result));
          }
        };
      }
    }
  };

  return (
    <input
      ref={fileUpload}
      type="file"
      id="file-upload"
      accept="application/json"
      className={classes.file}
      onChange={() => importQuestions()}
      style={{ display: "none" }}
    />
  );
};

using typescript with jest

Run in shell:

npm i --save-dev jest \
    @types/jest \
    babel-jest \
    @babel/core \
    @babel/preset-env \
    @babel/preset-typescript

Save to babel.config.js:

module.exports = {
  presets: [
    ["@babel/preset-env", { targets: { node: "current" } }],
    "@babel/preset-typescript",
  ],
};

using import inside module declarations

The import goes inside the declare module block:

// WRONG
import { AnotherClass } from "LibraryB";
declare module "LibraryA" {
  class SomeClass extends AnotherClass {}
}

// RIGHT
declare module "LibraryA" {
  import { AnotherClass } from "LibraryB";
  class SomeClass extends AnotherClass {}
}

finding circular dependencies

With dpdm:

npx dpdm --no-warning --no-tree ./src/main.tsx

With madge:

npx madge --circular --extensions ts ./src

generate type declarations from javascript

npx -p typescript tsc .\dist\*.js --declaration --allowJs --emitDeclarationOnly --outDir types

get readonly keys

type GetReadonlyKeys<T extends Object> = {
  [K in keyof T]: 
    (<S>() => S extends { [Z in K]: T[Z] } ? 2 : 1) extends 
    (<S>() => S extends { -readonly [Z in K]: T[Z] } ? 2: 1) ? never : K
}[keyof T]

module resolution

In older typescript projects, when adding or updating modules that have changed the source of their types, Visual Studio Code may no longer be able to resolve the module. To fix this, explicitly set moduleResolution to node in tsconfig.json:

{
    "compilerOptions": {
        "moduleResolution": "node",      
    }
}

posts