Я не знаю, сколько поклонников TS сетовали на эту проблему: хотя я очень хочу использовать TS, босс использует только JS. Сегодня я скажу вам, что вы можете без проблем использовать TypeScript в JavaScript, и ваш начальник не будет вас беспокоить.
серия статей
Первая фаза:"Руководство TS Amway"
Этот период:"TS in JS Practice Guide North"
написать впереди
Многие студенты смотрят"Руководство TS Amway"После этого он прокомментировал: "ТС ароматный, но нашему начальнику это не интересно", "Мне интересно, но нужно время, чтобы потихоньку внедрить. Нет возможности". В то время я чувствовал, что мой Амвей не в место, так что я проделал большую работу.После долгой подготовки я написал это продолжение, которое рассказывает о результате моего упорного изучения практики ТС в JS.
Если у вас есть основы TS, это будет плавное чтение. Если у вас нет основы ТС, вы можете кое-что понять (это тоже моя цель), но если она у вас есть, вы поймете глубже. Если вам не нравится TS, эммммммм... просто посмотрите его :P
Эта статья написана для последней версии VSCode (v1.41.0). В случае каких-либо расхождений с другими IDE преимущественную силу имеют официальные возможности IDE.
WebStorm также поддерживает его, но, поскольку он включает в себя собственный уникальный интеллектуальный движок, код, который не может быть затронут следующей строкой, также может быть найден в текущей области видимости, поэтому этот артефакт здесь обсуждаться не будет.
Что, ты пользуешься блокнотом?
Дружеское напоминание: основная среда зависимостей имеет только последнюю версию VSCode, и дополнительная настройка не требуется. Некоторые основные демонстрации в этой статье, нуждающиеся учащиеся могутэто здесьоказаться
Как это работает
ТС в VSCode
TypeScript — это инструмент, представленный Microsoft в 2012 году. Однако из-за того, что он родился в несвоевременное время, до выхода VSCode, он не получил широкого внимания в Китае.
Есть группа людей, которые осознают, что у JS есть потенциал изменить слабые стороны JS, и начинают принимать и применять эту технологию Многие из этих людей имеют опыт разработки. Они предпочитают преимущества статически типизированных языков, и, что наиболее важно, они используют IDE, такие как Visual Studio, Eclipse, которые поддерживают TypeScript. Но студенты, занимающиеся чистым фронтендом, редко выбирают такую тяжелую IDE. В то время большая часть чистого фронтенда использовала легковесную IDE вроде Sublime, которая имела немного отключенный интеллект (широко известный как умственная отсталость), и они не поддерживали TypeScript, что было похоже на написание кода в Блокноте. Работа с блокнотом может привести к аутизму. Поэтому, когда «большие шишки с полным стеком» шлепнули себя по заднице и ушли, пришедшие на смену одноклассники были несчастны и ненавидели ТС до глубины души.
После выхода VSCode у фронтенд-разработки наконец-то появилась профессиональная облегченная IDE. С ростом популярности VSCode во фронтенд-разработке TS был принят большим количеством фронтенд-разработчиков и начал свою эру. При использовании VSCode для написания JS-кода, нравится вам это или нет, используете ли вы TS или нет, вы непреднамеренно будете наслаждаться удобством, которое оно принесет.
ТС в JS
Не знаю, задумывались ли вы когда-нибудь, зачем играть в JSdocument.
, VSCode автоматически выведет в нем методы.
Это явно относится к сфере возможностей TS, но также влияет на JS?
Фактически, это также цель, которую TS ожидала достичь в начале своего создания: расширенная система типов и поддержка инструментов разработчика. В переводе: продвинутая система типов и поддержка средств разработки. TS сам по себе является надмножеством JS, поэтому некоторая поддержка JS также является одним из его ключевых показателей эффективности.
Возможности TS VSCode в среде JS исходят из библиотеки TS, которую содержит VSCode. VSCode IDE имеет встроенную папку node_modules, содержащую пакеты TypeScript. И в папке TypeScript есть несколько очень простых файлов объявлений api .d.ts.
Глядя на эту картинку, много ли знакомых названий методов? Он предоставляет возможности методов, связанных с Dom. Поэтому в самом JS, опираясь на этот документ, можно иметь возможность подсказывать Dom Api.
В JS объем TS на самом деле гораздо больше, чем вы думаете.
Элегантные файлы заголовка
Давайте поговорим об этом файле объявлений .d.ts, который предоставляет возможности хинтинга в JS.
Встроенный файл декларации
Как упоминалось выше, некоторые базовые API создаются непосредственно в VSCode IDE. Еще одна цель TS с самого начала: поддержка современных функций JavaScript. Говоря простым языком: использование современных возможностей JS.
Так что неудивительно, что VSCode имеет встроенные функции Dom и ES2015, ES2016, ES2017... синтаксиса. Однако по умолчанию VSCode поддерживает только возможности ES 2016. Если вам нужен дополнительный синтаксис, вы можете создать новый файл с именем в корневом каталоге.jsconfig.json
файл, затем введите следующее:
{
"compilerOptions": {
"lib": [
"dom",
"esnext"
]
}
}
Вы даже можете получить подсказки по синтаксису для ES2020.
Поскольку файл объявлений, который поставляется с VSCode, поддерживает только функции, сформулированные ECMAScript и W3C, но API, которые нам нужны в нашей разработке, намного больше, существует множество сторонних файлов объявлений.
Файл объявления, который поставляется с пакетом
Не указывать запись по умолчанию:
Некоторые файлы JS будут иметь свои собственные файлы объявлений. Пока файл декларации имеет тот же префикс, что и файл JS, VSCode автоматически импортирует файл декларации.
Например:
// urlLib.js
export function url1 (str) {
return 'url1'
}
export function url2 (str) {
return 'url1'
}
export function url3 (str) {
return 'url1'
}
// urlLib.d.ts
export function url1(str: string): string
export function url2(str: string): string
export function url3(str: string): string
Здесь следует отметить, что IDE будет иметь приоритет над типом API, определенным в файле объявления. Если файл объявления не содержит открытого метода, соответствующего файлу .js, IDE не будет подсказывать, что этот метод существует, и даже сообщит об ошибке при включении проверки синтаксиса.
Кроме того, VSCode имеет собственный набор правил порядка для импорта файлов объявлений, аналогичных правилам запроса узла. Если он слишком длинный, он не будет опубликован.кликните сюдаУзнать больше.
Укажите запись по умолчанию:
Файл объявления, который поставляется с пакетом, также может храниться в отдельной папке без исходного кода.Пока запись файла объявления указана в package.json, VSCode автоматически найдет этот файл. Например, в package.json Vue
существуетtypings
илиtypes
Укажите запись в свойствах , когда мы напрямуюimport Vue from 'vue'
, он будет искать указанный файл объявления.
Файл декларации от @types
Есть также некоторые пакеты, которые не помещают файлы объявлений в свой собственный каталог, а размещаются в частном домене, выделенном для файлов объявлений. Вероятно, самый известный пакет в частном домене — это @types/node.
Если вы хотите использовать файлы объявлений узла, вам необходимо установить @types/node.
npm i @types/node -D
Таким образом, API-интерфейсы, использующие node.js, обладают интеллектом.
Иногда вы можете обнаружить, что он не установлен@types/node
IDE также будет предлагать API Node.js. То есть потому, что VSCode найдет пакет типов в нескольких глобальных местах по умолчанию, и у вас есть подсказка.
Вам может быть интересно узнать об этом@types
Что такое домен. Ответ: домен Microsoft. Файлы деклараций, соответствующие спецификациям, могут быть размещены здесь для использования программистами/женщинами по всему миру. Если вы хотите иметь подсказку для node_modules, но в пакете нет файла объявления, вы можетеиди сюда, чтобы найти.
Конечно, вы также можете написать файл объявления в соответствии со спецификацией и опубликовать его для использования другими.кликните сюдаПри необходимости можно сделать PR.
Приложение: расширение возможностей типов с помощью файлов объявлений .d.ts.
Добавление возможности типа в файл объявления незаметно, и пользователю не нужно обращать внимание на содержимое файла объявления, что очень элегантно. Даже если программист, сидящий рядом с вами, ненавидит TS, этот метод гарантирует, что он почти не коснется кода TS во время использования.
Общие компоненты в Teams:
У фронтенд-команды будет много собственных общедоступных методов.Мы можем добавить файлы объявлений для некоторых общедоступных методов, поддерживаемых внутри, чтобы другие могли пользоваться преимуществами интеллектуальных подсказок при их использовании, уменьшая вероятность ошибок кода.
Заявление, такое как следующие документы для URL Lib:
// url.module.d.ts
/**
* url lib 工具包
*/
/** 格式化url */
export function formatUrl (a: string): string
/** 获取url参数 */
export function getParams (paramName: string): string
Храните файл объявления .d.ts и lib.js в одном и том же каталоге с тем же именем, например, /xxx/url.module.js и /xxx/url.module.d.ts.
можно использовать вот так
import * as urlLib from "./url.module"
IDE автоматически импортирует его для вас.url.module.d.ts
файл декларации.
глобальная переменная:
В передней части бизнеса, идиwindow
Работа с кипрскими глобальными переменными является обычным явлением. Заполнение и могут быть некоторые инструменты, тестирование и другие функции среды. В этом синтаксисе обычно используется код внутриwindow.XXCompanyLibs.url.format
для вызова функции. ноwindow.XXCompanyLibs
Для каких функций ниже обычно нужно идти в документацию или исходный код отдельно. Когда в команду приходят новые ученики, они будут растеряны, когда им нужно будет использовать эти публичные функции, а потом жалуются в емейле, что это реально неудобно делать.
Мы можем использовать файл объявления для объявления объекта в глобальной области видимости, чтобы другие мелкие партнеры, пишущие код в этой библиотеке, могли найти эту глобальную переменную в глобальной области видимости и почувствовать доброжелательность с вашей стороны.
// gbobal.d.ts
interface ILib {
/** 获取当前环境 */
getEnv: string
/** img方法 */
img: {
formatImg: (a: string, b: string) => string
}
/** url方法 */
url: {
formatUrl: (a: string) => string
}
}
/**
* xx公司全局变量
*/
declare var XXCompanyLib: ILib // 定义全局变量
Это включает в себя точки знаний метода раскрытия типа декларации.Студенты, которые заинтересованы в получении дополнительной информации о них, могуткликните сюдадля дальнейшего изучения.
волшебная записка
Когда дело доходит до комментариев в JS, все сразу думают о//
,/* */
Однако то, что я собираюсь представить здесь, это такая аннотация/** */
, который является комментарием в спецификации JSDoc.
/** 我是 JSDoc 注释 */
function foo () {}
JSDoc
JSDoc — это спецификация комментариев и инструмент для создания документации, с которым в той или иной степени сталкивались все.
Эту спецификацию приветствуют многие программисты из-за ее красивого формата. Также существует множество интерфейсных библиотек, которые используют его в качестве спецификации аннотации, например lodash.
В дополнение к этому JSDoc имеет некоторые функции, о которых вы, возможно, не знаете, так что давайте начнем здесь.
Какую проблему решает JSDoc:
Если область действия кода ясна, VSCode сам может определить связь через контекст и автоматически связать данные с логическими связями. Например, определите переменную, и когда она будет использоваться в следующей строке, VSCode узнает, откуда эта переменная.
Но в пользовательских функциях IDE не знает тип передаваемых параметров, поэтому входные параметры в этих функциях теряют тип и становятся любыми. Если тип возвращаемого значения также любой, переменная, назначенная функцией, также не имеет типа. Когда таких функций становится все больше и больше, половина кода становится каким-то сценарием.
function foo (a, b) {
document.querySelector('xxx') // 这里 IDE 知道 document.querySelector 是什么,以及返回了什么
console.log(a) // 这里 IDE 不知道 a 是什么,当 any 处理
console.log(b) // 这里 IDE 也不知道 b 是什么,也当 any 处理
return a // return any
}
var bar = foo(1, 2) // 由于在 foo 里面不知道 a 是什么,所以 bar 的类型成了 any
С другой стороны, если мы искусственно изменимthis
, также вызовет любой скрипт. потому чтоthis
может быть подтверждено только во время выполнения, в условиях неясностиthis
VSCode не понимает вас™ о цепочке областей видимостиthis
Что-то сделал. Эта проблема часто возникает с возвращаемым значением общедоступного метода.
Все вышеперечисленное можно решить через JSDoc.
Вы знаете JSDoc:
Согласно международной практике, начните с чего-то простого.
Пишем код вfunction
В это время, для того, чтобы следующие одноклассники, которые подберут яму, не пришли к вам на беду, обычно комментируют.
Использование комментариев в стиле JSDoc выглядит следующим образом:
/**
* 方法:foo
* @param {string} name
*/
function foo (name) {
console.log(name)
}
здесь/** ... */
Это типичный синтаксис JSDoc. в@param
Указывает, что метод получаетname
изstring
тип параметра.
В IDE, поддерживающих JSDoc, таких как VSCode и WebStorm, при наведении курсора на этот метод будет выдано дружественное приглашение.
JSDoc вы можете не знать:
На основе вышеизложенного давайте дополнительно изучим следующий код.
/**
* 方法:foo
* @param {string} name
*/
function foo (name) {
console.log(name)
return name
}
/**
* 方法:bar
*/
function bar (name) {
console.log(name)
return name
}
var _foo = foo('name') // _foo 为 string
var _bar = bar('name') // _bar 为 any
вот одинbar
метод, менее@param
и вернуть все входные параметры. Давайте посмотрим, какой у них тип возвращаемого значения:
можно увидеть, иметь@param
изfoo
Параметры, возвращаемые функцией, также имеют строковый тип.bar
Функция возвращает любое.
JSDoc добавляет к функциям типы входных параметров, чтобы среда IDE могла определить взаимосвязь между входными параметрами функции и выходными параметрами.
С другой стороны, внутри функции есть тип параметраfoo
аргументы функцииname
, IDE дала ему подсказкуstring
возможности внутреннего метода.
Вот как JSDoc решает проблему нехватки типов функций в JS. в JSDoc@param
этой марки, в{}
Середина представляет тип TS.
Связанный@param
изДокументы Нажмите здесь
Аналогично, исходя из вышесказанного, изменим содержимое JSDoc.
/**
* 方法:foo
* @param {{firstname: string, nameLength: number}} name
*/
function foo (name) {
console.log(name)
return name
}
В этом случае имя в функции не являетсяstring
, но обычайobject
Типы. Конечно, когда мы посещаемname
, ты получишьfirstname
а такжеnameLength
два свойства.
Помните «автозапрос файла конфигурации», упомянутый в «Руководстве TS Amway»?
/**
* webpack配置自动提示
*
* 先安装对应的types包: `npm i @types/webpack -D`
*
* @type {import('webpack').Configuration}
*/
const config = {}
Вот тот, что в JSDoc@type
Маркер, синтаксическая функция которого заключается в назначении указанного типа следующей единице.
Связанный@type
изДокументация нажмите здесь
Так называемый «автоматический запрос файла конфигурации» на самом деле является./node_modules/@types/webpack/index.d.ts
в файле декларацииConfiguration
type Тип берется и присваивается следующемуconfig
среди переменных.
Это также означает, что JSDoc может напрямую использовать файлы объявлений.
Элегантное использование JSDoc:
Когда некоторые студенты используют JSDoc для аннотирования метода, они напишут что-то вроде этого:
/**
* ajax 请求
* @example `ajax('url', options)`
* @param url 请求链接
* @param options ajax控制参数
* .jsonp 登录模式。'common'常规模式;'silent'静默模式;'forced'强制模式;'backendSilent'后台静默
* .async 强制登录标志,会忽略当前登录态再跑一次登录 // TODO 待废弃
* .methods 跳过三秒内拒绝授权限制
* .success 是否忽略本地缓存的登录态,设为true会重新发起登录请求
* @returns { Promise } 返回一个promise实例
*/
function ajaxOld (url, options) {}
Глядя на комментарии, вроде бы понятно, но в процессе вызова метода у IDE не будет подсказки для дружеского взаимодействия.
Глядя на подсказки IDE, мы даже не знаем, как пользоваться этой функцией.
Если вы хотите следовать характеру IDE и добиться более элегантного эффекта, вы можете спроектировать его следующим образом:
/**
* ajax方法
*
* @example `ajax('url', options)`
*
* @typedef {Object} IAjaxOptions
* @property {boolean} [jsonp] 是否jsonp
* @property {boolean} [async] 是否async
* @property {'GET'|'POST'} [methods] 请求方法
* @property {(options: any)=>void} [success] 成功回调函数
*
* @param {string} url url
* @param {IAjaxOptions} [options] 参数
* @param { Promise }
*/
function ajaxNew (url, options) {}
Эффект от его использования в VSCode следующий:
Во время использования IDE дает удобные подсказки для параметров.
Здесь два новых тега,@typedef
а также@property
.
в@typedef
Эффект состоит в том, чтобы объявить тип типа (или понять тип как псевдоним), например, вотobject
тип, названныйIAjaxOptions
.
а также@property
Роль состоит в том, чтобы объявить свойства, содержащиеся в вышеупомянутых типах, использовании и@param
Последовательный.
Связанный@typedef
изДокументация нажмите здесь
Кстати, в некоторых библиотеках есть много таких методов записи, которые мы обычно используем, но игнорируем, например этотhtml-webpack-plugin
Заинтересованные студенты могут перейти на github, чтобы узнать
Теги JSDoc, связанные с этим и поддерживаемые VSCode:
params
typedef
property
return
this
constructor
Дополнительные примеры можно найти в JSDoc.Официальный сайтИзолировано.
не используйте его вслепую
Некоторые учащиеся могут чувствовать себя немного неловко, увидев некоторые из приведенных выше примеров. Ваша интуиция остра. Этот метод, отмеченный JSDoc, имеет определенные риски, не используйте его вслепую. Чтобы продвигать сначала, давайте поговорим о проблемах, которые могут быть вызваны его слепым использованием.
вопрос:
-
полностью ручной Как видно из вышеприведенного примера, это «маркированная» грамматика, перестановка вручную. В крайних случаях вы можете столкнуться с необходимостью писать комментарии и декларации в половине случаев.
-
Его нелегко поддерживать, и для его ограничения требуются хорошие командные нормы или проектные документы. Некоторые люди могут писать больше, некоторые могут писать меньше, а третьи могут добавлять код без добавления объявлений в JSDoc.
-
Существует риск запутать область действия intellisense. Если статическая проверка типов не включена, среда IDE полностью примет созданный вами тип. Если вы принудительно указываете тип только для подсказки, которую вы хотите, не говорите, что я сказал вам этот метод (выполнить).
-
ограниченная способность Самое главное, JSDoc не является идеальным инструментом для дополнения типов в VSCode. Когда вы реализуете некоторые сложные типы, вы можете обнаружить, что эффект неудовлетворителен, не сомневайтесь в себе, это в значительной степени котел VSCode. Бог знает, сколько незабываемых ночей я провел, работая над ним.
Возможно, из-за того, что JSDoc больше используется для создания документов API, а соотношение спроса и предложения неравномерно, поддержка VSCode для JSDoc ограничена, и в его примечаниях к выпуску есть только некоторые прерывистые обновления. Вот несколько проблем, с которыми я столкнулся до сих пор
- не может поддерживать
@private
,@protected
Этот вид модификации тега по-прежнему указывается в подсказке. - Вы не можете определить перегрузку функции непосредственно для функции, вам нужно полагаться на форму объекта
- Многие теги не поддерживаются, например
@augments
,@mixin
Подождите, приведенные на официальном сайте примеры не могут показать ожидаемого эффекта в редакторе VSCode
выгода:
-
Умение выполнять простые Вместо изменения на .ts вам даже не нужно менять расширение файла.
-
Менее инвазивный код Возможно, написанные вами 300 строк кода с комментариями не переживут первую упаковку.
-
не беспокойтесь ни о каком сценарии Большое количество кода JS сам по себе является любым скриптом, как бы вы его ни меняли, это прогресс.
Упомянутые здесь преимущества резко контрастируют с проблемами, возникающими при дооснащении TS. Если вы не можете перейти на TS в своей команде, попробуйте использовать JSDoc.
Предложения по модернизации
С полным пониманием его недостатков и преимуществ, прежде чем вы решите официально использовать его в своем текущем коде, вы можете обратиться к следующим предложениям, которые могут помочь вам избежать некоторых скрытых опасностей:
Отдайте предпочтение «лечению первопричины»:
Сам VSCode имеет возможность логически ассоциироваться в среде JS. Затем мы должны сначала подумать, можем ли мы позволить IDE автоматически распознавать свою ассоциацию, исправляя некоторую логику.
взять каштан
var foo = {
b: 2
}
foo.a = 1
foo.a // IDE 找不到 'a'
можно изменить на
var foo = {
a: 1,
b: 2
}
foo.a // IDE 找到 foo.a
или
var foo = {}
foo.a = 1
foo.b = 2
foo.a // IDE 找到 foo.a
Больше внимания источникам данных из и JS:
Мы знаем, что в VSCode "ctrl + щелчок" эта операция может перейти к части определения текущей переменной или свойства. Позже мы будем называть это поведение "прямым переходом".
JSDoc имеет очень хорошее преимущество перед JS. Среди возможностей, связанных с TS, поведение «непосредственного перехода» в большинстве случаев определяет позицию объявления кода, а не позицию определения. Большинство программистов, работающих с JS, не хотят обращать внимание на объявление объектного кода, но хотят знать, что это за определение. Если использование типа в JS полностью зависит от файлов объявлений .d.ts, каждый «скачок» может отдалить истину еще дальше.
Поэтому на практике его следует использовать с умомtypeof
.
var foo = {
a: 2,
b: 2
}
/**
* @param {typeof foo} obj
*/
function bar (obj) {
obj.a // 「直跳」找到 foo 里定义的 a
}
Открыть проверку JS:
Хотя удобно использовать возможности типов, обеспечиваемые синтаксисом JSDoc, также необходимо обращать внимание на спецификации. Во многих случаях, хотя IDE распознается, но синтаксис не стандартизирован, лучше всего открыть настройки VSCodeCheck JS
или в верхней части кода с помощью// @ts-check
заметки.
Например следующий код:
var foo = {
a: 2,
b: 2
}
/** @type { typeof foo } */
var bar = {}
bar.a // ide可以关联到foo里面的a,但是bar并不包含这个属性
Этот код имеет очевидные ошибки, но поскольку тип назначается вручную, IDE может делать только то, что написано.
при включенииCheck JS
После этого IDE отобразит красную подсказку:
Соответствует закрытию текущего файлаCheck JS
Верхний комментарий это// @ts-nocheck
, игнорировать следующую строку TS ошибка// @ts-ignore
.
Добавлено в начало некоторых демонстраций GIF ранее в этой статье.// @ts-nocheck
, во избежание покраснения IDE и помех для понимания.
Добавить тип JSDoc к часто используемым объектам:
Если комментариев слишком много, это может повлиять на удобство чтения, и вы не сможете сразу изменить весь код на элегантный JSDoc. Поэтому рекомендуется добавлять дополнительные комментарии JSDoc только к часто используемым объектам, таким какzepto
, глобальные переменные, данные интерфейса и т. д.
Иногда мы используем библиотеку. Вы столкнетесь с конфликтами имен переменных, такими как
var $ = requireFn('zepto')
В большинстве случаев команда реализует собственный интерфейс.requireFn
функция не возвращаетzepto
тип.
В это время, если естьzepto
введите файл, вы можете сделать это:
/**
* @typedef { typeof $ } ZeptoStatic // 把 $ 换个名字
*/
/** @type { ZeptoStatic } */ // 再赋予给 $
var $ = require('zepto')
так что все$
имеютzepto
способность типа.
Вместо этого используйте JSDoc для комментирования кода.:
Мы часто используем по привычке//
Продолжайте комментировать код, но мы можем изменить стиль комментирования JSDoc, если нам все еще нужны подсказки IDE. Когда VSCode распознает JSDoc, он выдаст вам предустановленное приглашение:
// 这是bar
var bar = 1 // 这是也是bar
/** 这是foo */
var foo = 2
console.log(bar)
console.log(foo)
наведите мышь наconsole.log(xxx)
Назадxxx
Выше обратите внимание на подсказку IDE:
foo
С советами, которые мы написали в JSDoc.
Если вы можете заменить его на .ts, замените его на .ts:
Как я писал в TS Amway Guide. Хотя трансформировать JS в TS сложно, это безопаснее и полнее. Поэтому, если позволяют условия, его следует преобразовать в код ТС, ведь долгая боль не так коротка, как короткая боль.
Насчет того, как трансформироваться в ТС. Это не содержание этой статьи, поэтому я не буду объяснять это. Существует много хороших практик, связанных с этим. Вы можете найти это.
продвинутая практика
Два более полных практических сценария перечислены впереди, чтобы углубить понимание.
TS in JS with JSDoc
1. Потерянный тип параметра:
как говорится в названии. Когда входной параметр выходит через метод, а тип теряется, как элегантно установить соединение:
const args = {
a: 1,
b: 2
}
const fn = {
foo: function () {},
bar: function () {}
}
/**
* 合并两个作用域
*
* @returns { typeof args & typeof fn } // 这里用 returns 指定了返回类型
*/
function someMergeFn (args, fn) {
// ...
}
const newObj = someMergeFn(args, fn)
newObj.a // 直跳到上面 args.a
newObj.bar // 直跳到上面 fn.bar
Как показано в анимации,newObj.a
а такжеnewObj.bar
Вышеуказанная ссылка установлена.
Вот через JSDoc@returns
тег завершает тип параметра, так что указанный тип получается после вызова функции.
2. Аналогичноrequire
Тип потери пакетов, вызванный методом:
Многие старые коды имеют свои собственные методы загрузки других пакетов, которые вызываются здесьsomeRequireFn
Бар. Однако из-за проблемы, аналогичной 1, возвращаемый тип теряется.В настоящее время его можно получить следующими методами, и он имеет возможность «прыгать прямо» между файлами.
// otherService.js
;(function(global, factory){
factory()
})(this, function () {
var args = {
a: 1,
b: 2
}
var fn = {
foo: function () {},
bar: function () {}
}
/**
* @returns { typeof args & typeof fn }
*/
function someFactoryFn () {
// ...
}
var newObj = someFactoryFn()
return newObj
module && (module.exports = newObj) // 这里是 TS 暴露模块的语法
})
/**
* @type { import ('./otherService') } // 这里用 type 指定 newObj 的类型
*/
var newObj = someRequireFn('./otherService')
newObj.a // 直跳到otherService.js的args.a
newObj.bar // 直跳到otherService.js的fn.bar
надotherService.js
Это должно выполнить функцию напрямую, чтобы имитировать некоторые общие способы старого кода. Следует отметить, что он должен иметь открытый выход, такой как в тексте.
module && (module.exports = newObj)
Поскольку синтаксический анализ TS является полным статическим синтаксическим анализом, его не нужно учитывать.module.exports
Расположение в коде не влияет на бизнес-код.
Возможность «перескакивать» между файлами очень удобна при просмотре кода: когда вы хотите сослаться на то, что делает текущая функция, вам не нужно фильтровать их один за другим через глобальный поиск.
3. Более сложные сценарии:
Если JSDoc имеет ограниченные возможности, вы можете напрямую заимствовать более полные возможности TS для реализации, а затем комбинировать JSDoc для выполнения смешанных дублей:
// InterfaceJs.d.ts
export interface INewObj {
a: number
b: number
foo: () => void
bar: () => void
}
/**
* @type { import ('./InterfaceJs.d').INewObj } // 手动引入外部的 .d.ts 声明文件
*/
var newObj = someRequireFn('./otherService')
newObj.a // 直跳到InterfaceJs.d.ts定义的args.a
newObj.bar // 直跳到InterfaceJs.d.ts定义的fn.bar
Использование TS в Vue
Давайте рассмотрим практику в Vue.
Есть много способов использовать TS в Vue. один черезimport
Импортировано по умолчаниюVue
файл декларации. Одним из них является использование его стиля класса. Другой является наиболее распространенным, черезVue
Плагин для Vetur автоматически сопоставляет свой файл объявления.
Здесь, чтобы сказать несколько слов для этой вилки. Когда тыscript
используется в блокеexport default {}
Когда этот синтаксис,{}
Часть возможности типа связана со справкой плагина в его файле объявления.
Здесь мы смотрим на это с другой стороны, не полагаясь на возможности плагинов, не сильно модифицируя сам код, и используя официально предоставленные возможности TS.
Примечание. Следующий контент содержит общие точки знаний, учащиеся, которым нужно только подать заявку, могут напрямую перейти к заключительной части.
Причина, по которой Vue имеет возможности TS, заключается в том, чтоvue.d.ts
Существование файла объявления вместе с несколькими другими файлами документирует все возможности Vue. Тогда мы просто проходим@type
Внедрив его, вы можете использовать возможности типов Vue в JS.
Но здесь сделано только полдела. подумай об этом,new Vue()
То, что передается внутри, является объектом. из-заvue.d.ts
внутри, перейти кVue
изoptions
является универсальным объектом, но мы не можем использовать дженерики для объекта, поэтому нам нуженhelper
Функция для выполнения, содержание очень простое:
const vueOptionsTypeHelper = function (options) {
return options
}
Следующая работа заключается в определении входных параметров для этого метода, и, указав тип входных параметров, можно реализовать возможности TS.
оказатьсяvue.d.ts
код, учебаnew Vue
Что там передается.
export interface VueConstructor<V extends Vue = Vue> {
new <Data = object, Methods = object, Computed = object, PropNames extends string = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): CombinedVueInstance<V, Data, Methods, Computed, Record<PropNames, any>>;
new <Data = object, Methods = object, Computed = object, Props = object>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Record<keyof Props, any>>;
new (options?: ComponentOptions<V>): CombinedVueInstance<V, object, object, object, Record<keyof object, any>>;
// ...
}
Прочитав исходный код, я обнаружил три формы перегрузки конструктора, и, по наблюдениям, нам подходит вторая.
вoptions
Тип типа
ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>
Удалите его дженерики и зависимости и создайте новый с именемvue.helper.d.ts
файл объявления, содержимое которого следующее:
// vue.helper.d.ts
import Vue from 'vue'
import { ThisTypedComponentOptionsWithRecordProps } from 'vue/types/options'
export type VueComponentOptions = <
Data = object,
Methods = object,
Computed = object,
Props = object
>(options?: ThisTypedComponentOptionsWithRecordProps<Vue, Data, Methods, Computed, Props>)
=> object
МодернизацияvueOptionsTypeHelper
метод
/**
* @type { import ('./vue.helper').VueComponentOptions }
*/
const vueOptionsTypeHelper = function (options) {
return options
}
затем используйтеvueOptionsTypeHelper
заворачиватьoptions
,Например
const options = vueOptionsTypeHelper({
name: 'app',
components: {
App,
},
data () {
return {
shareDialog: false,
inWxapp: false,
}
},
methods: {
methods1 () {
return true
},
methods2 () {
return false
},
onclick () {
console.log(123)
}
},
created () {
},
mounted () {
this.methods1()
},
})
Таким образом, указанныйobject
естьVue
возможность подсказки типа .
Вы можете спросить, так какVue
Уже есть относительно полная практика использования возможностей типов в JS, так что толку от этого?
Вы можете подумать о том, есть ли в вашей команде подобныеVue
S рама? Рамка вашей команды - это просто расстояние файла декларации (небольшой голос BB: и написание этой декларации, возможно, придется потратить 95% всего процесса).
Подобных сценариев много, вы можете использовать свою фантазию, и я не буду их здесь повторять.
Суммировать
Контента много, вот краткое содержание.
Способы использования возможностей TS в JS
- использовать файл декларации
- Использование JSDoc
Эти два метода также могут работать вместе для достижения некоторых сложных эффектов шрифта.
как подать заявку
- Написать файлы объявлений для общедоступных компонентов и глобальных переменных
- Пишите комментарии JSDoc для пользовательских функций и элегантно дорабатывайте их.
- Используйте JSDoc для переменных без области видимости, объектов и т. д.
@type
, чтобы указать его тип
Меры предосторожности
- Не связывайтесь с JSDoc
- Попробуйте сделать так, чтобы код «прыгал прямо» туда, где он определен
Я упомянул об этом в начале, и я упомянул это снова позже: Студенты, которым нужно испытать демонстрацию непосредственно, могут щелкнутьздесь, потяните его вниз и испытайте локально с помощью VSCode.
напиши в конце
Когда я показал эту статью своим друзьям вокруг меня, я обычно сообщал о своем истощении по поводу ТС. Может травма была слишком глубокая, может руки на клавиатуре задавило окружающее противостояние, может просто познать жизнь и написать код, незачем жить с собой.
Что мне нравится в TS, так это то, что это автоматические предложения (опять же, пережиток статически типизированных языков). При более глубоком рассмотрении особенности ТС даже компенсируют некоторые мои собственные недостатки, такие как невнимательность. Глубокое чувство ведет к глубокому осознанию. Хотя это немного более громоздко писать, я оцениваю это выше неудобства, поэтому я пойду на это.
Сделайте шаг назад на 10 000 шагов и скажите, что когда вы идете на собеседование, люди спрашивают вас о ТС, вы также можете использовать это, чтобы одурачить его.
Если вы считаете, что этот контент ценен для вас, пожалуйста, поставьте лайк и подпишитесь на нашу фронтенд-команду.Официальный сайтА на нашем официальном аккаунте WeChat (WecTeam) каждую неделю публикуются качественные статьи: