不用 typescript 可以吗?

64 阅读2分钟

js 实现类型 提示方式

  1. 添加// @ts-check到文件的第一行
  2. 添加 tsconf.json / jsconfig.json 并让 checkJs 为 true。
{
  "compilerOptions": {
    "baseUrl": "./src",
    "checkJs": true
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}
  1. 更多参考 type-checking-javascript

实例

1.基础类型

列举一些常用的类型声明:

let num: number;

let win: Window;

let promisedString: Promise<string>;

let myElement: HTMLElement;

let oneAndTwo: 1 | 2;

let arr1: [number, string, { a: number; b: string }];

let star: any;

let sb: string | boolean;

let var9: { a: string; b: number };

let arrayLike: { [p: number]: any };

let sbn2: (s: string, b: boolean) => number;

js 注释 实现方式:

/** @type {number} */
let num;

/** @type {Window} */
let win;

/** @type {Promise<string>} */
let promisedString;

/** @type {HTMLElement} */
let myElement;

/** @type {1 | 2} */
let oneAndTwo;

/** @type {[number, string, {a: number; b: string}]} */
let arr1;

/**
* @type {*}
*/
let star;

/**
* @type {string | boolean}
*/
let sb;

/** @type {{ a: string, b: number }} */
let var9;

/** @type {Object.<number, object>} */
let arrayLike;

/** @type {(s: string, b: boolean) => number} */
let sbn2;

interface type

typescript

type SpecialType = {
  prop1: string;
  prop2: number;
  prop3?: number | undefined;
  prop4?: number;
  prop5?: number;
};
let specialTypeObject: SpecialType;

// interface Predicate {
//   (data: string, index?: number): boolean;
// }
type Predicate = (data: string, index?: number) => boolean;
const ok: Predicate = (s) => !(s.length % 2);

type options = {
  prop1: string;
  prop2: number;
  prop3?: number | undefined;
  prop4?: number;
  prop5?: number;
};
function special(options: options) {
  return (options.prop4 || 1001) + options.prop5;
}

js

/**
 * @typedef {object} SpecialType - 创建一个名为“SpecialType”的新类型
 * @property {string} prop1 - SpecialType的字符串属性
 * @property {number} prop2 - 一个SpecialType的数字属性
 * @property {number=} prop3 - SpecialType的可选数字属性
 * @prop {number} [prop4] - SpecialType的可选数字属性
 * @prop {number} [prop5=42] - 带有default的SpecialType的可选数字属性
 */

/** @type {SpecialType} */
let specialTypeObject;

/** @typedef {(data: string, index?: number) => boolean} Predicate1 */

/** @type {Predicate1} */
let ok1 = (s) => !(s.length % 2);

/**
 * @callback Predicate
 * @param {string} data
 * @param {number} [index]
 * @returns {boolean}
 */

/** @type {Predicate} */
let ok = (s) => !(s.length % 2);

/**
 * @param {object} options - The shape is the same as SpecialType above
 * @param {string} options.prop1
 * @param {number} options.prop2
 * @param {number=} options.prop3
 * @param {number} [options.prop4]
 * @param {number} [options.prop5=42]
 */
function special(options) {
  return (options.prop4 || 1001) + options.prop5;
}

这里有些校验规范的差异, typescript 对于可选属性会提示未定义错误,js 没有提示 ![[ts_check.png]] ![[js_check.png]]

Partial,Pick

  1. Partial

typescript

interface Todo {
  title: string;
  description: string;
}

function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
  return { ...todo, ...fieldsToUpdate };
}

js

/**
 * @typedef {object} Todo
 * @property {string} title
 * @property {string} description
 */

/**
 * @param {Todo} todo
 * @param {Partial<Todo>} fieldsToUpdate
 */
function updateTodo(todo, fieldsToUpdate) {
  return { ...todo, ...fieldsToUpdate };
}

const todo1 = {
  title: "organize desk",
  description: "clear clutter",
};

const todo2 = updateTodo(todo1, {
  description: "throw out trash",
});
  1. Pick

typescript

interface Todo3 {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo3, "title" | "completed">;

const todo3: TodoPreview = {
  title: "Clean room",
  completed: false,
}

js

/**
 * todo3
 * @typedef {object} Todo3
 * @property {string} title
 * @property {string} description
 * @property {boolean} completed
 */

/**
 * @typedef {object} TodoPreview
 * @type {Pick<Todo3, "title" | "completed">}
 */

/** @type {TodoPreview} */
const todo3 = {
  title: "Clean room",
  completed: false,
};

其他

typescript

type Config = {
  [k in "edit" | "new" | "del"]: Todo3;
};
let config: Config;

js

/**
 * @typedef {object} Config
 * @type {{[k in "edit" | "new" | "del"]: Todo3}}
 */

/** @type {Config} */
let config;

引入 d.ts

// test.d.ts
export type Pet = {
  name: string;
};
/**
 * @param {import("../types/test").Pet} p
 */
function walk(p) {
  console.log(`Walking ${p.name}...`);
}

参考