From e02835fa50d0862aabe9388c4fdd44d118d86e86 Mon Sep 17 00:00:00 2001 From: wxzhang Date: Mon, 3 Apr 2023 21:32:40 +0800 Subject: [PATCH] update for typescript --- packages/runtime/src/formatter.ts | 6 +- packages/runtime/src/interpolate.ts | 137 +++++++++++++++------------- packages/runtime/src/translate.ts | 6 +- packages/runtime/src/utils.ts | 5 +- 4 files changed, 83 insertions(+), 71 deletions(-) diff --git a/packages/runtime/src/formatter.ts b/packages/runtime/src/formatter.ts index 1398381..4d2474c 100644 --- a/packages/runtime/src/formatter.ts +++ b/packages/runtime/src/formatter.ts @@ -43,8 +43,8 @@ formatters="| aaa(1,1,"dddd") | bbb " */ //@returns [ [<格式化器名称>,[<参数>,<参数>,...],[<格式化器名称>,[<参数>,<参数>,...]],...] -export type FormatterDefines = ([string, string[]])[] -export function parseFormatters(formatters: string): FormatterDefines { +export type FormatterDefineChain = ([string, string[]])[] +export function parseFormatters(formatters: string): FormatterDefineChain { if (!formatters) return []; // 1. 先解析为 ["aaa()","bbb"]形式 let result = formatters.trim().substring(1).trim().split("|").map((r) => r.trim()); @@ -63,7 +63,7 @@ export function parseFormatters(formatters: string): FormatterDefines { } else { // 不带参数的格式化器 return [formatter, []]; } - }).filter((formatter) => Array.isArray(formatter)) as FormatterDefines + }).filter((formatter) => Array.isArray(formatter)) as FormatterDefineChain } diff --git a/packages/runtime/src/interpolate.ts b/packages/runtime/src/interpolate.ts index 66e620d..3c71c36 100644 --- a/packages/runtime/src/interpolate.ts +++ b/packages/runtime/src/interpolate.ts @@ -32,9 +32,9 @@ import { getDataTypeName } from "./utils" import { isNumber } from "flex-tools/typecheck/isNumber" import { isPlainObject } from "flex-tools/typecheck/isPlainObject" import { isFunction } from "flex-tools/typecheck/isFunction" -import { parseFormatters } from "./formatter" +import { FormatterDefineChain, parseFormatters } from "./formatter" import { VoerkaI18nScope } from "./scope" -import { SupportedDateTypes } from "./types" +import { SupportedDateTypes, VoerkaI18nFormatter, VoerkaI18nFormatterConfigs } from './types'; // 用来提取字符里面的插值变量参数 , 支持管道符 { var | formatter | formatter } // 支持参数: { var | formatter(x,x,..) | formatter } @@ -56,48 +56,12 @@ function hasInterpolation(str:string):boolean { return str.includes("{") && str.includes("}"); } -/** - * 解析格式化器的参数 - * -/** - * 提取字符串中的插值变量 - * [ - // { - name:<变量名称>,formatters:[{name:<格式化器名称>,args:[<参数>,<参数>,....]]}],<匹配字符串>], - // .... - // - * @param {*} str - * @param {*} isFull =true 保留所有插值变量 =false 进行去重 - * @returns {Array} - * [ - * { - * name:"<变量名称>", - * formatters:[ - * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, - * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, - * ], - * match:"<匹配字符串>" - * }, - * ... - * ] - */ -function getInterpolatedVars(str:string) { - let vars = []; - forEachInterpolatedVars(str, (varName, formatters, match) => { - let varItem = { - name: varName, - formatters: formatters.map(([formatter, args]) => { - return {name: formatter,args: args }; - }), - match: match, - }; - if (vars.findIndex((varDef) =>varDef.name === varItem.name && varItem.formatters.toString() ==varDef.formatters.toString()) === -1){ - vars.push(varItem); - } - return ""; - }); - return vars; -} + + +export type InterpolatedVarReplacer = (varname:string,formatters:FormatterDefineChain,matched:string)=>string; +// [,[,[,,...]]] +export type VarFormatters = [string,[string,any[]]]; + /** * 遍历str中的所有插值变量传递给callback,将callback返回的结果替换到str中对应的位置 * @param {*} str @@ -105,7 +69,7 @@ function getInterpolatedVars(str:string) { * @param {Boolean} replaceAll 是否替换所有插值变量,当使用命名插值时应置为true,当使用位置插值时应置为false * @returns 返回替换后的字符串 */ -function forEachInterpolatedVars(str:string, replacer, options = {}) { +function forEachInterpolatedVars(str:string, replacer:InterpolatedVarReplacer, options = {}) { let result = str, matched; let opts = Object.assign({replaceAll: true },options); varWithPipeRegexp.lastIndex = 0; @@ -239,6 +203,7 @@ function getFormatter(scope:VoerkaI18nScope, activeLanguage:string, name:string) } } } +export type FormatterChecker = (value:any,config?:VoerkaI18nFormatterConfigs)=>any; /** * Checker是一种特殊的格式化器,会在特定的时间执行 @@ -250,7 +215,7 @@ function getFormatter(scope:VoerkaI18nScope, activeLanguage:string, name:string) * @param {*} value * @returns */ -function executeChecker(checker, value,scope) { +function executeChecker(checker:FormatterChecker, value:any,scope:VoerkaI18nScope) { let result = { value, next: "skip" }; if (!isFunction(checker)) return result; try { @@ -261,7 +226,7 @@ function executeChecker(checker, value,scope) { result.value = r; } if (!["break", "skip"].includes(result.next)) result.next = "break"; - } catch (e) { + } catch (e:any) { if(scope.debug) console.error("Error while execute VoerkaI18n checker :"+e.message) } return result; @@ -274,17 +239,16 @@ function executeChecker(checker, value,scope) { * 这样格式化器可以读取$config * * @param {*} value - * @param {Array[Function]} formatters 多个格式化器函数(经过包装过的)顺序执行,前一个输出作为下一个格式化器的输入 + * @param {FormatterDefineChain} formatters 经过解析过的格式化器参数链 ,多个格式化器函数(经过包装过的)顺序执行,前一个输出作为下一个格式化器的输入 + * formatters [ [<格式化器名称>,[<参数>,<参数>,...],[<格式化器名称>,[<参数>,<参数>,...]],...] */ -function executeFormatter(value, formatters, scope, template) { +function executeFormatter(value:any, formatters:FormatterDefineChain, scope:VoerkaI18nScope, template:string) { if (formatters.length === 0) return value; let result = value; // 1. 空值检查 - const emptyCheckerIndex = formatters.findIndex( - (func) => func.$name === "empty" - ); + const emptyCheckerIndex:number = formatters.findIndex((func) => (func as any).$name === "empty") if (emptyCheckerIndex != -1) { - const emptyChecker = formatters.splice(emptyCheckerIndex, 1)[0]; + const emptyChecker = formatters.splice(emptyCheckerIndex, 1)[0] as unknown as FormatterChecker const { value, next } = executeChecker(emptyChecker, result,scope); if (next == "break") { return value; @@ -293,10 +257,10 @@ function executeFormatter(value, formatters, scope, template) { } } // 2. 错误检查 - const errorCheckerIndex = formatters.findIndex((func) => func.$name === "error" ); + const errorCheckerIndex = formatters.findIndex((func) => (func as any).$name === "error" ); let errorChecker; if (errorCheckerIndex != -1) { - errorChecker = formatters.splice(errorCheckerIndex, 1)[0]; + errorChecker = formatters.splice(errorCheckerIndex, 1)[0] as unknown as FormatterChecker if (result instanceof Error) { result.formatter = formatter.$name; const { value, next } = executeChecker(errorChecker, result,scope); @@ -337,7 +301,7 @@ function executeFormatter(value, formatters, scope, template) { * * @param {*} formatters */ -function addDefaultFormatters(formatters) { +function addDefaultFormatters(formatters:FormatterDefineChain) { // 默认的空值处理逻辑: 转换为"",然后继续执行接下来的逻辑 if (formatters.findIndex(([name]) => name == "empty") === -1) { formatters.push(["empty", []]); @@ -364,18 +328,18 @@ function addDefaultFormatters(formatters) { * @returns {Array} [(v)=>{...},(v)=>{...},(v)=>{...}] * */ -function wrapperFormatters(scope, activeLanguage, formatters) { +function wrapperFormatters(scope:VoerkaI18nScope, activeLanguage:string, formatters:FormatterDefineChain) { let wrappedFormatters = []; addDefaultFormatters(formatters); for (let [name, args] of formatters) { let fn = getFormatter(scope, activeLanguage, name); let formatter; if (isFunction(fn)) { - formatter = (value, config) =>fn.call(scope.activeFormatterConfig, value, ...args, config); + formatter = (value:any, config:VoerkaI18nFormatterConfigs) =>fn.call(scope.activeFormatterConfig, value, args, config); } else { // 格式化器无效或者没有定义时,查看当前值是否具有同名的原型方法,如果有则执行调用 // 比如padStart格式化器是String的原型方法,不需要配置就可以直接作为格式化器调用 - formatter = (value) => { + formatter = (value:any) => { if (isFunction(value[name])) { return value[name](...args); } else { @@ -383,7 +347,8 @@ function wrapperFormatters(scope, activeLanguage, formatters) { } }; } - formatter.$name = name; + // 为格式化器函数添加一个$name属性,用来标识当前格式化器的名称 + (formatter as any).$name = name; wrappedFormatters.push(formatter); } return wrappedFormatters; @@ -393,11 +358,11 @@ function wrapperFormatters(scope, activeLanguage, formatters) { * 将value经过格式化器处理后返回的结果 * @param {*} scope * @param {*} activeLanguage - * @param {*} formatters + * @param {*} formatters * @param {*} value * @returns */ -function getFormattedValue(scope, activeLanguage, formatters, value, template) { +function getFormattedValue(scope:VoerkaI18nScope, activeLanguage:string, formatters:FormatterDefineChain, value, template) { // 1. 取得格式化器函数列表,然后经过包装以传入当前格式化器的配置参数 const formatterFuncs = wrapperFormatters(scope, activeLanguage, formatters); // 3. 执行格式化器 @@ -468,4 +433,50 @@ export function replaceInterpolatedVars(this:VoerkaI18nScope,template:string, .. { replaceAll: false } ); } -} \ No newline at end of file +} + + + + +// /** +// * 解析格式化器的参数 +// * +// /** +// * 提取字符串中的插值变量 +// * [ +// // { +// name:<变量名称>,formatters:[{name:<格式化器名称>,args:[<参数>,<参数>,....]]}],<匹配字符串>], +// // .... +// // +// * @param {*} str +// * @param {*} isFull =true 保留所有插值变量 =false 进行去重 +// * @returns {Array} +// * [ +// * { +// * name:"<变量名称>", +// * formatters:[ +// * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, +// * {name:"<格式化器名称>",args:[<参数>,<参数>,....]}, +// * ], +// * match:"<匹配字符串>" +// * }, +// * ... +// * ] +// */ +// function getInterpolatedVars(str:string) { +// let vars = []; +// forEachInterpolatedVars(str, (varName, formatters, match) => { +// let varItem = { +// name: varName, +// formatters: formatters.map(([formatter, args]) => { +// return {name: formatter,args: args }; +// }), +// match: match, +// }; +// if (vars.findIndex((varDef) =>varDef.name === varItem.name && varItem.formatters.toString() ==varDef.formatters.toString()) === -1){ +// vars.push(varItem); +// } +// return ""; +// }); +// return vars; +// } \ No newline at end of file diff --git a/packages/runtime/src/translate.ts b/packages/runtime/src/translate.ts index ff879d3..c6d3572 100644 --- a/packages/runtime/src/translate.ts +++ b/packages/runtime/src/translate.ts @@ -72,7 +72,7 @@ function getPluraMessage(messages:any,value:number){ * this===scope 当前绑定的scope * */ -export function translate(this:VoerkaI18nScope,message:string,...args:any[]) { +export function translate(this:VoerkaI18nScope,message:string,...args:any[]):string { const scope = this const activeLanguage = scope.global.activeLanguage // 如果内容是复数,则其值是一个数组,数组中的每个元素是从1-N数量形式的文本内容 @@ -141,12 +141,12 @@ export function translate(this:VoerkaI18nScope,message:string,...args:any[]) { } // 进行插值处理 if(vars.length==0){ - return result + return result as string }else{ return replaceInterpolatedVars.call(scope,result as string,...vars) } }catch(e){ - return result // 出错则返回原始文本 + return result as any // 出错则返回原始文本 } } \ No newline at end of file diff --git a/packages/runtime/src/utils.ts b/packages/runtime/src/utils.ts index ff36bd5..67082a3 100644 --- a/packages/runtime/src/utils.ts +++ b/packages/runtime/src/utils.ts @@ -1,4 +1,5 @@ import { isNumber } from "flex-tools/typecheck/isNumber" +import { SupportedDateTypes } from './types'; /** * 获取指定变量类型名称 @@ -12,9 +13,9 @@ import { isNumber } from "flex-tools/typecheck/isNumber" * @param {*} v * @returns */ -export function getDataTypeName(v:any):string{ +export function getDataTypeName(v:any):SupportedDateTypes{ if (v === null) return 'Null' - if (v === undefined) return 'Undefined' + if (v === undefined) return 'Undefined' if(typeof(v)==="function") return "Function" return v.constructor && v.constructor.name; };