分类
未分类

typescript 给ws添加属性类型报错怎么解决?类型“WebSocket”上不存在属性xxx

其实很简单 我以我这边使用的ws库为例子 新建一个 shims.d.ts 文件

import ws from "ws";

declare module "ws" {
  export interface WebSocket extends ws {
    $id: string;
  }
}

这样就可以实现扩展了,成功的在ws 上扩展了$id属性

另外注意一点 d.ts文件不要和.ts文件一样命名 不推荐通过后缀区分文件

还有疑问可以加群讨论 秋秋群:768901972

分类
未分类

deno的初体验-环境安装与第一个程序

denoDeno 的目标是为现代程序员提供一个高效、安全的脚本环境。

它始终以单个可执行文件形态,作为分发文件,并且该可执行文件,足够运行任何 deno 程序。

给定一个 deno 程序的 URL,您应该能够用不超过 50MB 的 Deno 可执行文件,来执行它。

Deno 明确承担运行时,和包管理器的角色。它用标准的浏览器兼容协议,来加载模块:URLs。

Deno 为提供了程序访问系统的安全保证,默认情况下,它是最严格的安全沙盒。Deno 提供一套经过评审(审核)的标准模块这保证了与 Deno 的合作。
windows 下安装Deno 在 OSX、Linux 和 Windows 上工作。deno 是单个二进制可执行文件。它没有外部依赖关系。deno_install提供方便的脚本,来下载和安装二进制文件。

使用 Shell:

$ curl -fsSL https://deno.land/x/install/install.sh | sh

使用 PowerShell:

> iwr https://deno.land/x/install/install.ps1 | iex

使用Scoop(Windows):

scoop install deno


也可以通过github.com/denoland/deno/releases下载 tarball 或 zip 文件,手动安装 deno。这些包只包含一个可执行文件。您必须在 Mac 和 Linux 上,设置可执行的环境变量(PATH)。

安装完成之后初体验
新建一个 helloworld.ts在里面写下

console.log("hello world");

终端中运行

deno run .\helloworld.ts

新建一个 a.ts

export const a = {  name: "i am a",};

在helloworld.ts中引入

import { a } from "./a.ts";
console.log("hello world",a.name);

注意a.ts 的后缀目前版本并不能省略,需要明确写出

先体验到这里,后续在更新

分类
angular 技术

记一次写TS时,遇到的坑

当有时候想要创建一个 [[],[],[]]的时候,你会用什么方式尼?

[...Array(3)].fill([]);

[...Array(3)].map(i=>[]);

亦或者会想到

Array(3).fill(0).map(i=>[])

来给大家比较下这三个的区别

[...Array(3)].fill([]);

有坑,相信不少人也遇到过,具体的表现 可以看一下这段代码

var b = [...Array(3)].fill([]);
b[0].push('qiupu'); 
console.log(b);
// 0: ["qiupu"]
// 1: ["qiupu"]
// 2: ["qiupu"]

这个就不再多解释了,看不懂的可以加下群768901972

[...Array(3)].map(i=>[]);

在JS里写的时候是没有问题的,

var a = [...Array(3)].map(i=>[]); 
a[0].push('qiupu');
console.log(a);
// 0: ["qiupu"]
// 1: []
// 2: []

Array(3).fill(0).map(i=>[])

这个看着和上面那个没什么区别,就多了一次fill(0),那他的意义是什么,就是先填充0,避免了 TS 在转译目标为ES5的 将他编译为 Array(20).slice().map(function (i) { return []; })

这篇文章主要是告诉大家,目前的TS的转译可能还存在一定的问题,使用的时候,应该注意下,特别是空值的处理之类的,希望能帮到你

提供一个在线测试工具,方便没有TS环境

分类
未分类

解决input的图片会旋转的问题

理论原因就是,苹果手机拍摄的图片,会把旋转信息存在 EXIF 里,读取这里的信息就可以旋转图片。

直接上代码

export function chooseFile(type) {
  return new Promise(function (ok) {
    const form = document.createElement('form');
    // tslint:disable-next-line
    form.innerHTML = `<input name=file type=file multiple accept="${type}" />`;
    const input: any = form.querySelector('input');
    input.onchange = function () {
      if (!input.files) { return; }
      foreachlistasync(input.files).then(
        (files) => {
          ok(files);
        }
      );
    };
    input.click();
  });
}


function foreachlistasync(filelist: FileList) {
  const Promises = Array.from(filelist).map((filepromise) => {
    return rotateImage(filepromise);
  });
  return Promise.all(Promises);
}

function rotateImage(file: File): Promise<File> {
  return new Promise((resolve, reject) => {
    // 过滤掉非 jpg的
    if (file.type === 'image/jpeg') {
      EXIF.getData(file, () => {
        const orientation = EXIF.getTag(file, 'Orientation');
        // console.log('orientation', orientation);
        changepic(file, orientation).then(
          (result: File) => {
            resolve(result);
          }
        );
      });
    } else {
      resolve(file);
    }
  });
}

function changepic(file: File, orientation: number) {
  return new Promise((resolve, reject) => {
    switch (orientation) {
      case 1:
        resolve(file);
        break;
      case undefined:
        resolve(file);
        break;
    }
    // 读取图片为 base64
    readFile(file).then(
      (base64) => {
        const form = document.createElement('form');
        form.innerHTML = `<img src="${base64}" />`;
        const img: any = form.querySelector('img');
        img.onload = () => {
          const width = img.width;
          const height = img.height;
          const canvas = document.createElement('canvas');
          canvas.height = width;
          canvas.width = height;
          const ctx = canvas.getContext('2d');
          switch (orientation) {
            case 6:
              ctx.rotate(Math.PI / 2);
              ctx.translate(0, -height);
              ctx.drawImage(img, 0, 0);
              const imageData6 = canvas.toDataURL('Image/jpeg', 0.9);
              const result6 = dataURLtoFile(imageData6, file.name);
              resolve(result6);
              break;
            case 3:
              ctx.rotate(Math.PI);
              ctx.translate(-width, -height);
              ctx.drawImage(img, 0, 0);
              const imageData3 = canvas.toDataURL('Image/jpeg', 0.9);
              const result3 = dataURLtoFile(imageData3, file.name);
              resolve(result3);
              break;
            case 8:
              ctx.rotate(-Math.PI / 2);
              ctx.translate(-height, 0);
              ctx.drawImage(img, 0, 0);
              const imageData8 = canvas.toDataURL('Image/jpeg', 0.9);
              const result8 = dataURLtoFile(imageData8, file.name);
              resolve(result8);
              break;
          }
        };
      }
    );
  });
}
function dataURLtoFile(imageData, filename) {
  // tslint:disable-next-line: one-variable-per-declaration
  const arr = imageData.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename, { type: mime });
}

function readFile(file) {
  return new Promise((resolve, reject) => {
    const fr = new FileReader();
    fr.onload = () => {
      resolve(fr.result);
    };
    fr.readAsDataURL(file);
  });
}