TypeScript 之 JavaScript文件类型检查

解密TMS320F28377D双核工程中的内存分配艺术:从CMD文件到实战优化 本文深入解析TMS320F28377D双核DSP的内存管理艺术,从CMD文件配置到实战优化技巧。详细介绍了SARAM、GSRAM等内存类型的特性与配置方法,提供双核协同、性能优化及高级调试的实用方案,帮助开发者提升系统实时性和稳定性。 阅读详情

启用对 JavaScript 文件的类型检查

在 TypeScript 编译选项 compilerOptions 全部配置项 中,可以通过以下2个属性配置 JavaScript Support:

  • allowJs

    • 是否允许编译 JavaScript 文件。
    • 默认值是 false。在默认情况下,TypeScript 编译器只处理 .ts、.tsx和 .d.ts文件,不会编译 .js文件。
  • checkJs

    • 是否对 JavaScript 文件进行类型检查。
    • 默认值是 false。在默认情况下,TypeScript 编译器不会对 JavaScript 文件进行类型检查。

在 tsconfig.json 中配置:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "target": "es5",
    "module": "commonjs",
    "strict": true
  }
}

类型检查的范围和限制

  1. 类型推断:TypeScript 会尝试对 JavaScript 文件中的变量和函数进行类型推断。例如,如果一个变量被赋值为一个字符串,TypeScript 会推断该变量的类型为字符串。注意:由于 JavaScript 是动态类型语言,类型推断可能不是完全准确的。
  2. 函数参数和返回值:对于有明确参数和返回值类型注释的 JavaScript 函数,TypeScript 可以进行更严格的类型检查。如果函数的实际参数类型与注释不匹配,或者返回值类型与预期不符,TypeScript 会报告错误。
  3. 模块导入和导出:当 JavaScript 文件使用模块导入和导出时,TypeScript 可以检查导入和导出的类型是否匹配。但是,如果导入的模块没有类型声明文件(.d.ts),类型检查可能会受到限制。

添加注释忽略类型检查

使用 // @ts-nocheck 忽略类型检查

// @ts-nocheck 注释可以用来忽略对特定 JavaScript 文件的类型检查。

如果"allowJs": true,"checkJs": true,,需要对某个JavaScript文件关闭类型检查,可以在文件的顶部添加 // @ts-nocheck 注释:

// @ts-nocheck
function add(a, b) {
  return a + b;
}

const result = add("Hello", 5);
console.log(result);

这样,TypeScript 在处理这个文件时将忽略类型检查,不会报告错误。

使用 // @ts-check 开启类型检查

如果"allowJs": true,"checkJs": false,,但是要对某个JavaScript文件进行类型检查,可以添加 // @ts-check 注释:

// @ts-check
function multiply(a, b) {
  return a * b;
}

const product = multiply(3, "four");
console.log(product);

当 TypeScript 处理这个文件时,会报告类型错误。

使用 // @ts-ignore 忽略特定行的错误

如果"allowJs": true,"checkJs": true,,需要让 TypeScript 忽略JavaScript文件某一行的类型检查错误,可以该语句上方添加// @ts-ignore 注释:

let a = 10;  // ts 类型检查 推断 a 是number

a = 'hello world'; // 报错:不能将类型“string”分配给类型“number”。

// @ts-ignore
a = 'hello world';  // 类型检查错误被忽略,不会报错

// @ts-ignore 仅仅对紧随其后的那一行代码做约束,可以写在代码的任意位置

使用// @ts-expect-error忽略特定行的错误

如果"allowJs": true,"checkJs": true,,需要让 TypeScript 忽略JavaScript文件某一行的类型检查错误,可以该语句上方添加// @ts-expect-error注释:

let a = 10;  // ts 类型检查 推断 a 是number

a = 'hello world'; // 报错:不能将类型“string”分配给类型“number”。

// `// @ts-expect-error`
a = 'hello world';  // 类型检查错误被忽略,不会报错

// @ts-expect-error与 // @ts-ignore 的区别:
如果随后一行代码是没有类型错误,代码提示器就会认为@ts-expect-error 没有被使用。 @ts-ignore不会有提示。
在这里插入图片描述

JavaScript 用 JSDoc 来 明确类型信息

.js文件里,类型可以和在.ts文件里一样被推断出来。如同TypeScript,--noImplicitAny会在编译器无法推断类型的位置报错。

所有JSDoc支持的模式,请看JSDoc中文文档。

使用JSDoc来明确类型信息:

  • 使用 @param 标签来指定函数参数的类型
  • 使用 @return 标签来指定函数的返回值类型。

示例:

/**
 * @param {number} num1 - The first number.
 * @param {number} num2 - The second number.
 * @return {number} - The sum of the two numbers.
 */
function sum(num1, num2) {
  return num1 + num2;
}
// 使用示例
console.log(sum( 'hello', 10 )); // 报错:类型“string”的参数不能赋给类型“number”的参数。

在这个例子中,使用 @param {number} num1 和 @param {number} num2 来指定函数 sum 的两个参数都是数字类型。
sum( 'hello', 10 ) 会报错:类型“string”的参数不能赋给类型“number”的参数。
在这里插入图片描述

TS支持的JSDoc

下面的列表列出了当前所支持的JSDoc注解,你可以用它们在JavaScript文件里添加类型信息。

注意,没有在下面列出的标记(例如@async)都是还不支持的。

  • @type
  • @param (or @arg or @argument)
  • @returns (or @return)
  • @typedef
  • @callback
  • @template
  • @class (or @constructor)
  • @this
  • @extends (or @augments)
  • @enum

@type

可以使用@type标记并引用一个类型名称(原始类型,TypeScript里声明的类型,或在JSDoc里@typedef标记指定的) 可以使用任何TypeScript类型和大多数JSDoc类型。

语法:

@type {type} - description

示例:

/**
/**
 * @type {Object} person
 * @property {string} name - The person's name.
 * @property {number} age - The person's age.
 */

let person = {
  name: 'John',
  age: 36,
  address: 'xxxxx'
}

变量person 有两个明确的属性,name 是字符串类型,用于表示人的名字;age 是数字类型,用于表示人的年龄。但是又不止这两个属性,没有明确定义的属性address 也不会报错。


指定对象字面量类型(使用 {} 来表示对象类型,并列出对象的属性和类型):

/** @type {{name: string, age: number}} */
let person = { name: 'John', age: 30 };
person = { name: 'John', age: 30, address: 'xxxxx' }; // 报错

在这里插入图片描述

有多种方式来指定数组,其中 type 是数组元素的类型:

  • @type Array<type>
  • @type Array.<type>
  • @type {type[]}

示例:

/** @type {Array<number>} */
let arr = [1, 2, 3];
arr.push('abc'); // 报错:类型“string”的参数不能赋给类型“number”的参数。

@type {Array<number>} 指定数组的每项元素的类型是number。


使用 | 来表示联合类型:

/** @type {Array<number | string>} */
let arr = [1, 2, 3];
arr.push('abc');

现在,数组的每项元素的类型是 number 或 string。

在类型后面加上 ? 表示该类型是可选的:

/** @type {{name: string, age?: number}} */
let person = { name: 'John' };
person.age = 36;

可以使用字符串和数字索引签名来指定map-like和array-like的对象,使用标准的JSDoc语法或者TypeScript语法:

/**
 * A map-like object that maps arbitrary `string` properties to `number`s.
 *
 * @type {Object.<string, number>}
 */
let stringToNumber;

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

这两个类型与TypeScript里的{ [x: string]: number }和{ [x: number]: any }是等同的。编译器能识别出这两种语法。

分析示例:

  • 第一个类型注释
    • “A map-like object that maps arbitrary string properties to numbers.”这个描述清晰地说明了这个对象的预期用途,即它是一个类似映射(map)的对象,将任意的字符串属性映射到数字。
    • @type {Object.<string, number>}表示这个变量 stringToNumber 被期望是一个对象,其键为字符串类型,值为数字类型。

使用示例:

/**
 * A map-like object that maps arbitrary `string` properties to `number`s.
 *
 * @type {Object.<string, number>}
 */
let stringToNumber = {
  key1: 10,
  key2: 20
};
  • 第二个类型注释
    • @type {Object.<number, object>}表明变量 arrayLike 被期望是一个对象,其键为数字类型,值为任意对象类型。

这种类型注释可以用于表示一个类似数组的对象,其中数字键可以用来模拟数组的索引,而值可以是各种不同类型的对象。

使用示例:

/** @type {Object.<number, object>} */
let arrayLike = {
  0: { name: 'obj1' },
  1: { name: 'obj2' }
};


指定一个对象是 Window ,该对象应该具有 Window 对象的属性和方法:

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

win.alert('Hello!');


指定一个变量 是一个类似于 Promise 的对象,并且这个 Promise 最终会 resolve 为一个字符串值:

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

在这个示例中:

  • Promise 类似对象:
    • 在 JavaScript 中,Promise 是一种用于处理异步操作的机制。它代表了一个尚未完成但预期在未来完成的操作,并提供了一种方式来处理操作成功(resolved)或失败(rejected)的情况。
    • PromiseLike 表示具有与 Promise 类似的行为的对象。它不一定完全符合 Promise 的规范,但可能具有 .then() 和 .catch() 等方法,用于处理异步操作的结果。
      注意:PromiseLike<string> 期望的 .then() 方法应该接受两个可选的回调函数,一个用于处理成功的情况,一个用于处理失败的情况。
  • 字符串结果:
    • @type {PromiseLike<string>}指定了这个 Promise 类似对象最终会产生一个字符串类型的结果。当这个异步操作完成时,可以预期从这个对象中获取一个字符串值。

指定变量是一个HTMLElement 类型的对象:

/** @type {HTMLElement} */
let myElement = document.querySelector(selector);
element.dataset.myData = '';

在这个示例中:
@type {HTMLElement}表明变量 myElement 被期望是一个 HTMLElement 类型的对象。在 JavaScript 中,HTMLElement 代表 HTML 文档中的一个元素。


使用TypeScript或Closure语法指定函数类型:

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

在这个示例中:

  • JSDoc 类型注释(Closure 语法)
    • @type {function(string, boolean): number}:
      这个 JSDoc 类型注释表明变量 sbn 被期望是一个函数类型。这个函数接受两个参数,第一个参数是字符串类型(string),第二个参数是布尔类型(boolean),并且这个函数返回一个数字类型(number)的值。
  • TypeScript 类型注释语法
    • @type {(s: string, b: boolean) => number}:
      这是使用 TypeScript 类型注释语法来指定变量 sbn2 的类型。同样,它表示 sbn2 是一个函数,接受一个字符串参数 s 和一个布尔参数 b,并返回一个数字。

用法示例:

/** @type {function(string, boolean): number} Closure syntax */
let sbn = function (str, bool) {
  // 根据字符串和布尔值进行一些操作并返回一个数字
  if (bool) {
    return str.length;
  } else {
    return 0;
  }
};

/** @type {(s: string, b: boolean) => number} Typescript syntax */
let sbn2 = function (s, b) {
  return b ? s.length : -1;
};

console.log(sbn('Hello', true));  // 5
console.log(sbn2('World', false)); // -1

直接使用未指定的Function类型:

/** @type {Function} */
let fnOne;
/** @type {function} */
let fnTwo;

在 JavaScript 中,Function (or function)是所有函数的类型。使用这个注释意味着 fnOne 、fnTwo可以被赋值为任何函数。


Closure的其它类型也可以使用:

/**
 * @type {*} - can be 'any' type
 */
let star;
/**
 * @type {?} - unknown type (same as 'any')
 */
let question;

类型注释说明:

  • @type {*} :
    这个 JSDoc 类型注释表明变量 star 可以是任何类型。在一些情况下,使用 * 表示“any”类型是为了在文档中明确指出该变量的类型是不确定的或者可以是任意类型。
  • @type {?} :
    这个 JSDoc 类型注释表明变量 question 的类型是未知的,并且说它与“any”类型相同。

转换

在括号表达式前面使用@type标记,可以将一种类型转换成另一种类型:

/**
 * @type {number | string}
 */
 
 // 根据随机数的结果,将变量 numberOrString 赋值为字符串 "hello" 或者数字 100。
let numberOrString = Math.random() < 0.5 ? "hello" : 100;

// 类型断言:将 numberOrString 断言为数字类型,并赋值给 typeAssertedNumber。
let typeAssertedNumber = /** @type {number} */ (numberOrString)

导入类型

可以使用导入类型从其它文件中导入声明。 这个语法是TypeScript特有的,与JSDoc标准不同:

/**
 * @param p { import("./a").Pet }
 */
function walk(p) {
  console.log(`Walking ${p.name}...`);
}
  • @param p { import("./a").Pet }:
    这个 JSDoc 类型注释表明函数 walk 的参数 p 是从模块 ./a 中导入的类型为 Pet 的对象。这指定了参数 p 的预期类型。

如果模块 ./a 定义了 Pet 类型如下:

// 模块./a
export class Pet {
  constructor(name) {
    this.name = name;
  }
}

可以这样使用 walk 函数:

import { Pet } from './a';
const myPet = new Pet('Fluffy');
walk(myPet);

导入类型也可以使用在类型别名声明中:

/**
 * @typedef Pet { import("./a").Pet }
 */

/**
 * @type {Pet}
 */
let myPet; // myPet 的类型 是 Pet 的类型别名。
myPet.name;
  • @typedef Pet { import("./a").Pet }:
    这里使用 @typedef 定义了一个名为 Pet 的类型别名。它表示这个新定义的 Pet 实际上是从模块 ./a 中导入的类型。
  • @type {Pet}
    这个类型注释表明变量 myPet 的类型是前面定义的 Pet 类型别名,也就是从模块 ./a 中导入的那个类型。

导入类型可以用在从模块中得到一个值的类型:

/**
 * @type {typeof import("./a").x }
 */
let x = require("./a").x;
  • @type {typeof import("./a").x }:
    这个 JSDoc 类型注释表明变量 x 的类型是模块 ./a 中导出的变量 x 的类型。具体来说,typeof import("./a").x 获取了模块 ./a 中 x 的类型信息,这里使用这个类型信息来注释变量 x,表示变量 x 应该与模块 ./a 中的 x 具有相同的类型。
  • let x = require("./a").x:
    这行代码使用 CommonJS 模块规范的 require 函数导入模块 ./a,并将模块中导出的 x 赋值给变量 x。

@typedef

在 JSDoc 中,@typedef 用于定义一个类型别名。

语法:

@typedef {type} name - description

其中,type 是现有的类型,name 是新定义的类型别名,description 是对这个类型别名的描述。

示例:

/**
 * @typedef {Object} Person
 * @property {string} name - The person's name.
 * @property {number} age - The person's age.
 */

/**
 * @param {Person} person - A person object.
 */
function greet(person) {
  console.log(`Hello, ${person.name}! You are ${person.age} years old.`);
}

const person1 = { name: 'John', age: 30 };
greet(person1);

在这个例子中,@typedef 定义了一个名为 Person 的类型别名,它是一个对象类型,包含 name(字符串类型)和 age(数字类型)两个属性。然后,函数 greet 接受一个参数 person,其类型被注释为 Person,表示这个参数应该是一个符合 Person 类型定义的对象。

@type 和 @typedef 的区别

  • @type
    • 用于指定一个变量、参数或返回值的具体类型。它通常用于为已有的类型提供类型注释,而不是创建新的类型别名。
  • @typedef
    • 用于定义一个新的类型别名。它允许你为一个复杂的类型结构创建一个更具描述性的名称,以便在代码中重复使用。

@param和@returns

在 JSDoc 中,@param用于描述函数的参数。
@param语法:

@param {type} name - description

其中 type 是参数的类型,name 是参数的名称,description 是对参数的描述。

注意:@param语法和@type相同,但增加了一个参数名。 使用[]可以把参数声明为可选的。


在 JSDoc 中,@returns用于描述函数的返回值。
@returns语法:

@returns {type} - description

其中 type 是函数的返回值类型,description 是对返回值的描述。

示例:

/**
 * @param {number} a - The first number.
 * @param {number} b - The second number.
 * @param {number=} c - The third number.
 * @param {number} [d=10] - The fourth number.
 * @returns {number} 
 */
function sum(a, b, c, d = 10) {
  c = c ?? 0;
  return a + b + c + d;
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, undefined, undefined)); // 3
console.log(sum(1, 2, undefined, 10)); // 13

参数c和d被标记为可选参数。在调用函数时它们可能没有被传入值。因此,需要对参数进行类型判断。

@typedef 与 @param

@typedef可以声明复杂类型。它和@param在语法上有一定的相似性,但用途不同。

使用@typedef 定义一个包含多个属性的对象类型别名:

/**
 * @typedef {Object} Person
 * @property {string} name - The person's name.
 * @property {number} age - The person's age.
 * @property {string[]} hobbies - The person's hobbies.
 */

/**
 * @param {Person} person - A person object.
 */
function displayPersonInfo(person) {
  console.log(`Name: ${person.name}, Age: ${person.age}, Hobbies: ${person.hobbies.join(', ')}`);
}

@param允许使用相似的语法。 注意,嵌套的属性名必须使用参数名做为前缀:

/**
 * @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) {
  let op5 = options.prop5 ?? 0;
  return (options.prop4 || 1001) + op5;
}

使用@typedef声明函数类型的别名:

/**
 * @typedef {(a: number, b: number) => number} MathOperation
 */

/**
 * @param {MathOperation} operation - A math operation function.
 * @param {number} x - The first number.
 * @param {number} y - The second number.
 */
function performMathOperation(operation, x, y) {
  return operation(x, y);
}

在这个例子中,定义了一个名为MathOperation的函数类型别名,代表接受两个数字参数并返回一个数字的函数类型。在函数performMathOperation中使用了MathOperation来注释参数operation。

@param {MathOperation} operation - A math operation function.:这个参数注释表明参数 operation 的类型是前面定义的 MathOperation,即一个特定的函数类型。这意味着在调用这个函数时,传入的 operation 参数应该是一个接受两个数字参数并返回一个数字的函数。

@callback

在 JSDoc 中,@callback用于定义回调函数的类型。

语法:

@callback callbackName - description

其中,callbackName是回调函数的名称,用于在文档中引用这个回调函数类型。description是对回调函数的描述。
在@callback的注释块内部,可以使用@param和@returns等标签来描述回调函数的参数和返回值类型。

示例:

/**
 * @callback ProcessFunction
 * @param {string} data - The input data.
 * @returns {number} The processed result.
 */

/**
 * Processes data using a callback function.
 * @param {string} inputData - The data to process.
 * @param {ProcessFunction} callback - The callback function to process the data.
 */
function processData(inputData, callback) {
  const result = callback(inputData);
  return result;
}

在这个例子中:

  1. 使用@callback定义了一个名为ProcessFunction的回调函数类型,它接受一个字符串类型的参数data,并返回一个数字类型的值。
  2. 在函数processData的文档注释中,使用这个回调函数类型来注释参数callback,表示这个参数应该是一个符合ProcessFunction类型定义的回调函数。

@template

在 JSDoc 中,@template用于描述函数或类的模板参数。

语法:

@template {typeParam} name - description

其中,typeParam是模板参数的类型,name是模板参数的名称,description是对模板参数的描述。

使用@template声明泛型:

/**
 * @template T
 * @param {T} x - A generic parameter that flows through to the return type
 * @return {T}
 */
function someArg(x){ return x }

console.log(someArg(5)); // 5
console.log(someArg('hi')); // 'hi'
const obj = { name: "John", age: 30 };
console.log(someArg(obj)); // { name: "John", age: 30 }

使用 @template 声明了一个模板参数 T。
@param {T} x表明函数接受一个参数 x,其类型为模板参数 T。
@return {T}明确了函数的返回值类型也是模板参数 T。
函数换入的参数类型与返回值的类型保持一致。

用逗号或多个标记来声明多个类型参数:

/**
 * @template T,U,V
 * @template W,X
 */

可以在参数名前指定类型约束。
例如,对第一个参数的类型进行严格的限制:

/**
 * @template {string} K - K must be a string or string literal
 * @template {{ serious(): string }} Seriousalizable - must have a serious method
 * @param {K} key
 * @param {Seriousalizable} object
 */
function seriousalize(key, object) {
  // ????
}

@template {string} K定义了一个模板参数 K,并限制其类型为字符串或字符串字面量。
也就是说,在调用函数seriousalize时,第一个参数 key 的类型必须是字符串或字符串字面量。

一个综合示例:

/**
 * @template T
 * @function mapArray
 * @param {T[]} array - The input array.
 * @param {(item: T) => T} callback - The callback function to apply to each item.
 * @returns {T[]} The mapped array.
 */

function mapArray(array, callback) {
  return array.map(callback);
}

const numbers = [1, 2, 3];
const doubledNumbers = mapArray(numbers, (num) => num * 2);
console.log(doubledNumbers); // [2, 4, 6]

const strings = ['a', 'b', 'c'];
const upperCaseStrings = mapArray(strings, (str) => str.toUpperCase());
console.log(upperCaseStrings); // ['A', 'B', 'C']

在这个例子中,@template T定义了一个模板参数T,表示函数mapArray可以接受任何类型的数组,并对数组中的每个元素应用一个回调函数。函数mapArray的参数array被注释为T[],表示一个类型为T的数组,参数callback被注释为(item: T) => T,表示一个接受类型为T的参数并返回类型为T的函数。

@class (or @constructor)

在 JSDoc 中,@constructor用于标记一个函数为构造函数。

语法:

@constructor通常放在函数的文档注释中,紧跟在函数的描述之后。

示例:

/**
 * A simple class representing a person.
 * @constructor
 * @param {string} name - The person's name.
 * @param {number} age - The person's age.
 */
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person('John', 30);
console.log(person1.name);
console.log(person1.age);

在这个例子中,@constructor标记了函数Person为构造函数。当使用new关键字调用Person函数时,它会创建一个新的对象,并将传入的参数赋值给对象的属性。

使用@constructor,可以明确一个函数是用于创建对象的构造函数。
不幸的是,这意味着那些既能构造也能直接调用的构造函数不能使用@constructor。

@this

编译器通常可以通过上下文来推断出this的类型。
在 JSDoc 中,@this用于描述函数中 this 的类型。

语法:

@this {type} - description

其中,type是 this 的类型,description是对 this 的描述。

明确this指向“上下文对象”:

/**
 * @this {Object} context - The context object.
 * @param {number} a - The first number.
 * @param {number} b - The second number.
 * @returns {number} The sum of the two numbers.
 */
function sum(a, b) {
  return this.a + this.b;
}

const context = { a: 5, b: 3 };
const result = sum.call(context, context.a, context.b);
console.log(result); // 8

在这个例子中,@this {Object} context - The context object.表示在函数 sum 中,this 的类型是一个对象,描述为“上下文对象”。通过 sum.call(context, context.a, context.b) 调用函数 sum ,并将 context 作为 this 的值传入,从而可以在函数内部使用 this.a 和 this.b 来访问 context 对象的属性。

明确this指向HTML 元素对象:

/**
 * @this {HTMLElement}
 * @param {*} e
 */
function callbackForLater(e) {
  this.style.height = parseInt(e) + 'px';
}

@this {HTMLElement}:
这个注释表明在函数 callbackForLater 中,this 的类型被期望为 HTMLElement。当这个函数被调用时,this 应该指向一个 HTML 元素对象。

@extends (or @augments)

在 JSDoc 中,@extends用于表示一个类型继承自另一个类型。

语法:

@extends {type} - description

其中,type是被继承的类型,description是对继承关系的描述。

当JavaScript类继承了一个基类,无处指定类型参数的类型。而@extends标记提供了这样一种方式:

/**
 * @template T
 * @extends {Set<T>}
 */
class SortableSet extends Set {
  // ...
}

注意@extends只作用于类。当前,无法实现构造函数继承类的情况。

@enum

在 JSDoc 中,@enum用于定义枚举类型。

语法:

@enum {Object} name - description

其中,name是枚举的名称,description是对枚举的描述。在注释块内部,可以使用键值对的形式来定义枚举的成员。

@enum标记允许创建一个对象字面量,它的成员都有确定的类型。与JavaScript里大多数的对象字面量不同:它不允许添加额外成员。

/** @enum {number} */
const JSDocState = {
  BeginningOfLine: 0,
  SawAsterisk: 1,
  SavingComments: 2,
}

注意JSDoc 的@enum与TypeScript的@enum大不相同,JSDoc 的@enum可以是任何类型。这意味着可以根据需要定义枚举成员的值为数字、字符串或其他复杂的数据类型。

例如,可以定义一个枚举,其中成员的值是对象或函数:

/**
 * @enum {Object} MyEnum
 * @property {function(): void} Action1 - Description of Action1.
 * @property {function(): void} Action2 - Description of Action2.
 */

不支持的写法

对象字面量中标记属性可选是不能使用=后缀的:

// 错误示例
const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3=: 'value3' // 错误的语法,不能用 =: 来表示可选属性
};

// 正确的写法是使用 ? 表示可选属性
const obj = {
  prop1: 'value1',
  prop2: 'value2',
  prop3?: 'value3' // 正确的语法,表示 prop3 是可选属性
};

Nullable类型只在启用了strictNullChecks检查时才起作用:

/**
 * @type {?number}
 * With strictNullChecks: true -- number | null
 * With strictNullChecks: off  -- number
 */
var nullable;

@type {?number}描述变量 nullable 的类型可以是number或者 null。


Non-nullable类型没有意义,以其原类型对待:

/**
 * @type {!number}
 * Just has type number
 */
var normal;
如何通过 GitHub Actions 使用 SSH 自动化部署到阿里云 ECS 实例 通过 GitHub Actions 和 SSH 自动化部署,可以显著提高你的开发效率和部署的可靠性。本文介绍了如何生成 SSH 密钥、将公钥添加到阿里云 ECS 实例、将私钥添加到 GitHub Secrets,以及编写 GitHub Actions 工作流来实现自动化部署。希望这篇文章对你有所帮助! 阅读详情

相关推荐

intel-VROC raid卡驱动 centos7.9

u盘进入系统,按e,在出现下面在quiet前面输入inst.dd initcall_blacklist=vmd_drv_init 后按Ctrl和x,开始引导。进入系统,按e,在出现下面在quiet前面输入inst.dd inicll_blacklist=vmd_drv_init 后按Ctrl和x,开始引导。驱动完成后,在输入 c 回车, 引导过程开始,进入安装界面。输入1 ,选择这个ISO驱动文件里的rpm包。输入1 ,选择这个ISO驱动文件里的rpm包。vi编辑 /etc/default/grub。

dacming的博客 4541

@ts-check @ts-expect-error @ts-ignore @ts-nocheck 有什么区别

这些注释都是用于TypeScript 代码中的类型检查。他们的作用是控制编译器对特定代码段的类型检查行为。

m0_73154039的博客 3794

CST-Python(Pycharm如何与CST联合仿真,获取S参数)

我们想使用Python与CST联合仿真,其实是不需要自己下载Python的,因为CST在下载的时候就自带了Python3.6,我们只需要找到并将软件的环境设置到相应位置,即可联合仿真。(我的保存路径为D:\Program Files (x86)\CST Studio Suite 2020,在寻找时可以将前面切换成自己的保存路径,后面不需要修改)在CST帮助文档(打开CST软件,按F11即可直接访问帮助文档)里面,进行如下操作,便可以看到CST适配的Python版本为Python3.6!

weixin_52696285的博客 5648

Typescript编译常见选项

之前编写完ts后可以在命令行中输入tsc ts文件名,来编译生成js文件,当我们的ts文件更改的时候还是需要手动的通过命令来编译生成新的文件,此时就不太方便了,这个时候我们就需要 tsc ts文件名 -w (watch:看,观察),这条命令,让编译器自动观察ts文件的变动后进行自动编译, 此处我们使用上面的监视命令,发现了一个问题,一个命令窗口只能够监视一个ts文件,如果项目中ts文件有很多,可想而知这种方法是行不通的 此时我们希望有一个命令可以将所有的ts文件一次性编译而且同时监视 此时我们就.

m0_57254953的博客 2409

antdv-<a-form>的使用

是 Ant Design Vue 中用于创建表单的组件,提供了一种结构化的方式来收集用户输入。它支持多种布局、验证、数据绑定等功能,非常适合用于处理用户输入和提交数据。

2302_81312344的博客 2619

【随机过程】 3 - 随机过程的频域分析1 - 功率谱

随机过程的频域分析 文章目录随机过程的频域分析1. 什么是谱2. 确定信号的频谱2.1 周期信号的频谱2.2 非周期信号的频谱3. 随机信号的谱3.1 随机信号做傅里叶分析的困难3.2 功率谱密度的物理和数学表示形式3.2.1 功率谱密度的物理表示3.2.2 功率谱密度的数学表示3.3 功率谱密度的解读3.3.1 量纲分析3.3.2 谱3.3.3 密度3.3.4 wiener和khinchin3.4 功率谱密度的性质3.4.1 非线性3.4.2 偶函数3.5 wiener-khinchin关系的应用3.6

qq_41741344的博客 3132

TypeScript的类型指令(单行注释)

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。 如图) `@ts-expect-error` : 期望随后那一行的代码的有类型错误. 还有一点与`@ts-ignore`不同的是, 如果随后一行代码是没有类型错误,代码提示器就会认为`@ts-expect-error` 没有被使用`unused` 如图。

小陈的博客 5650

安卓刷Windows太难?这款手机平板双系统刷机工具,小白也能轻松拿捏!(小白福音!手机平板专用,一键搞定安卓刷 Windows 双系统!)

安卓刷Windows太难?这款手机平板双系统刷机工具,小白也能轻松拿捏!(小白福音!手机平板专用,一键搞定安卓刷 Windows 双系统!)

XiaoqiangClub的博客 4676

【Vue Error】Virtual script not found, may missing <script lang=“ts“> “allowJs“: true / jsconfig.json

翻译过来意思就是:有可能在配置中没有添加允许JS的配置(

道阻且长,行则将至。 2824

Vue2 - 最新实现接入使用天地图及卫星视图切换功能,在国家天地图上自由切换地图显示类型(卫星视图/地形视图/卫星混合/地形混合/普通视图)vue天地图切换视图显示改成卫星风格,切换地图图层完整代码

vue2,nuxt2,天地图,视图,卫星,地图类型切换,vue天地图,改成卫星视角,在线地图切换,来回切换卫星图,天地图如何实现来回切换卫星图,地形图,卫星视图,vue中使用天地图自定义样式切换地图图层,切换报错,加载出错,卫星图太卡,地图图层更换,vue安装集成天地图详细示例源码,切换地图的样式,在天地图中如何将地图的类型随意更换,提供多种视图模式用户自由点击更换,VUE引入天地图卫星版,详细教程示例源码代码,天地图切换卫星用什么api,卫星视角API方法,vue2卫星天地图,能改地图的显示方式,图层类型

🏆 前端领域优质创作者 4140

JavaFX 概述

要从 JavaFX 中充分受益,了解 JavaFX 的设计方式以及对 JavaFX 包含的功能有一个很好的概述是很有用的。本文的目的是为您提供 JavaFX 概述。本文将首先介绍一般的 JavaFX 设计,然后介绍 JavaFX 中的各种特性。如果您熟悉 Flash/Flex,您会发现 JavaFX 在某种程度上受到了 Flash/Flex 的启发。JavaFX 中也有一些相同的想法。一般来说,JavaFX 应用程序包含一个或多个对应于窗口的阶段。每个阶段都有一个场景。

2012年开始工作,全栈开发老兵,目前已是一个老师,分享这么多年的心得体会 407

TS——取消校验的注释

【代码】TS——取消校验的注释。

qq812457115的博客 3489

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

TypeScript与JavaScript文件类型检查:如何为现有JS项目添加类型安全

TypeScript作为JavaScript的超集,提供了强大的**类型检查**功能,让开发者能够在现有JavaScript项目中逐步引入类型安全。通过**TypeScript类型检查**,你可以在不重写整个项目的情况下,显著提升代码质量和开发体验。本指南将教你如何为现有的JavaScript项目添加TypeScript类型检查,实现渐进式类型安全。 ## 🔍 为什么需要为JS项目添加类型检查

gitblog_01200的博客 827

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TypeScript 中的 JavaScript 文件类型检查

在 JavaScript 项目中引入 TypeScript 类型检查有助于提高代码质量、减少潜在的 bug,并且使得代码更易于理解和维护。虽然 TypeScript 并不是 JavaScript 的替代品,但它可以作为 JavaScript 项目的有力补充,为开发人员提供更强大的工具来构建可靠的应用程序。总的来说,通过逐步引入 TypeScript 类型检查,你可以在 JavaScript 项目中获得更好的开发体验,同时也为将来可能的迁移到完全的 TypeScript 代码打下了基础。

lostdeer 511

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

TypeScript项目中的JavaScript文件类型检查指南

TypeScript作为JavaScript的超集,不仅支持.ts文件,还提供了对.js文件的类型检查能力。本文将深入探讨如何在TypeScript项目中充分利用这一特性,提升JavaScript代码的类型安全性。 ## 启用JavaScript文件类型检查 从TypeScript 2.3版本开始,开发者可以通过`--checkJs`编译器选项为.js文件启用类型检查功能。这一特性为大型项目中...

gitblog_01160的博客 517

TypeScript学习-22 JavaScript文件类型检查

22 JavaScript文件类型检查JavaScript文件类型检查用JSDoc类型表示类型信息属性的推断来自于类内的赋值语句构造函数等同于类支持CommonJS模块类,函数和对象字面量是命名空间对象字面量是开放的null,undefined,和空数组的类型是any或any[]函数参数是默认可选的由arguments推断出的var-args参数声明未指定的类型参数默认为any在extends语句中:在JSDoc引用中:在函数调用中支持的JSDoc@type转换导入类型@param和@returns@typ

贰十二的博客 1810

TypeScript基础入门之Javascript文件类型检查(一)

转载 TypeScript基础入门之Javascript文件类型检查(一) TypeScript 2.3及更高版本支持使用--checkJs在.js文件中进行类型检查和报告错误。 您可以通过添加//@ts-nocheck注释来跳过检查某些文件; 相反,您可以通过在不设置--checkJs的情况下向其添加//@ts-check注释来选择仅检查几个.js文件。 您还可以通过在前一行添加//@ts-...

zhangda89的专栏 1064

YOLOv8车牌识别系统:检测与字符识别两阶段实战全流程

在计算机视觉项目中,目标检测用于定位目标位置,OCR技术负责将图像中的文字转录为字符串,两者共同构成完整的图像识别系统。车牌识别作为经典的应用场景,企业级智慧停车与卡口抓拍均依赖车牌检测与字符识别的协同工作。仅靠YOLOv8完成车牌定位并不等于实现了车牌号识别,检测框的坐标输出还需经过裁剪、预处理与OCR模块才能生成最终字符串。基于YOLOv8与PaddleOCR的两阶段架构,能够有效降低端到端模型的标注成本与调试难度,同时兼顾模块解耦与工业落地灵活性。本文以毕业设计为背景,给出从数据集准备、YOLOv8训

weixin_34288121的博客 733

TypeScript基础入门之Javascript文件类型检查(五)

转发 TypeScript基础入门之Javascript文件类型检查(五) 继续上篇文章【TypeScript基础入门之Javascript文件类型检查(四)】 @constructor 编译器根据此属性赋值推断构造函数,但如果添加@constructor标记,则可以更好地检查更严格和更好的建议: /** * @constructor * @param {number} data ...

zhangda89的专栏 310

TypeScript基础入门之Javascript文件类型检查(二)

转发 TypeScript基础入门之Javascript文件类型检查(二) 继续上篇文章【TypeScript基础入门之Javascript文件类型检查(一)】 对象文字是开放式的 在.ts文件中,初始化变量声明的对象文字将其类型赋予声明。不能添加未在原始文本中指定的新成员。此规则在.js文件中放宽;对象文字具有开放式类型(索引签名),允许添加和查找最初未定义的属性。例如: var ob...

zhangda89的专栏 482

TypeScript基础入门之Javascript文件类型检查(三)

转发 TypeScript基础入门之Javascript文件类型检查(三) 继续上篇文章【TypeScript基础入门之Javascript文件类型检查(二)】 支持JSDoc 下面的列表概述了使用JSDoc注释在JavaScript文件中提供类型信息时当前支持的构造。 请注意,尚不支持下面未明确列出的任何标记(例如@async)。 @type @param (or @arg or @...

zhangda89的专栏 315

LayaBox---TypeScript---JavaScript文件类型检查

1.介绍TypeScript2.3以后的版本支持使用--checkJs对.js文件进行类型检查和错误提示。可以通过添加//@ts-nocheck注释来忽略类型检查;相反,你可以通过去掉--checkJs设置并添加一个//@ts-check注释来选则检查某些.js文件。你还可以使用//@ts-ignore来忽略本行的错误。如果你使用了tsconfig.json,JS检查将遵照一些严格检查标记,如noImplicitAny等。.js文件和.ts文件在类型检查上的差异,有如下几点需要注意。...

学海无涯 699

【亲测免费】 Vue.js ESLint 配置 TypeScript 项目的常见问题解决方案

Vue.js ESLint 配置 TypeScript 项目的常见问题解决方案 Vue.js ESLint 配置 TypeScript 项目是一个为 Vue 3 + TypeScript 开发环境设计的 ESLint 配置项目。它的主要编程语言是 JavaScript 和 TypeScript。 新手在使用这个项目时需要特别注意的3个问题及解决步骤 问题1:如何安装项目依赖 问题描述: 新手在使用...

gitblog_00580的博客 1209

ts引入js时的类型检查

项目由js向ts转型时,若使用import的方式引入js文件,则在脚本检查ts时,会报错找不到这些js文件,造成ts检查日志里有很多同样的信息,因此很难找到真正的ts报错信息,有如下三种解决方案

爬不上树的小松鼠 2233
上一篇: TypeScript 构建工具之 webpack
下一篇: TypeScript Mixins
fishmemory7sec
博客等级 码龄5年 1165粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值