tadcode-wpsjs 0.3.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
  - [**WPS多维表格:“开发”功能使用说明文档**](https://365.kdocs.cn/l/ctzsgDlAGF0l)
6
6
  - [**执行AirScript脚本操作使用指南**](https://365.kdocs.cn/l/cdQOqc6TZuMk)
7
7
  - [**快速入门多维表“开发”**](https://365.kdocs.cn/l/ctx1jAV1xJhR)
8
+ - [**WPS开放平台dbsheet-Api部分**](https://365.kdocs.cn/3rd/open/documents/app-integration-dev/guide/dbsheet/Api/api-instro)
8
9
 
9
10
  ## 联系我
10
11
 
@@ -51,11 +52,11 @@ const scriptToken = 'xxxx'
51
52
  /* webhook url地址 具体获取方式参考上面 */
52
53
  const webhookURL = 'xxxx'
53
54
  const wpsjsGlobal = initRemoteCallWpsjsGlobal({ scriptToken, webhookURL, })
54
- const data = await wpsjsGlobal.Application.Sheet.GetSheets().execution()
55
+ const data = await wpsjsGlobal.Application.Sheet.GetSheets()
55
56
  console.log(data)
56
57
  ```
57
58
 
58
- ### 对于智能表格执行赋值操作
59
+ ### 重命名(远程赋值操作)
59
60
 
60
61
  ```ts
61
62
  import { initRemoteCallWpsjsGlobal } from 'tadcode-wpsjs'
@@ -64,17 +65,9 @@ const scriptToken = 'xxxx'
64
65
  /* webhook url地址 具体获取方式参考上面 */
65
66
  const webhookURL = 'xxxx'
66
67
  const wpsjsGlobal = initRemoteCallWpsjsGlobal({ scriptToken, webhookURL, })
67
- const values = [
68
- ['name', 'price'],
69
- ['米', 2.5],
70
- ]
71
- function setValue(data: any[][], rangeReference = 'a1') {
72
- const rowCount = data.length
73
- const columnCount = data[0].length
74
- wpsjsGlobal.Application.ActiveSheet.Range(rangeReference).Resize(rowCount, columnCount).Value2 = data
75
- return wpsjsGlobal.execution() as unknown as boolean
76
- }
77
- setValue(values)
68
+ /* 类型完善中 */
69
+ wpsjsGlobal.Application.Sheets(1).Name = 'new table4'
70
+ console.log(data)
78
71
  ```
79
72
 
80
73
  ### 执行脚本并且返回(不用部署remoteCode代码)
package/index.js CHANGED
@@ -1 +1 @@
1
- import{writeFile as G}from"fs/promises";import $ from"path";var O=(B)=>{let{scriptToken:E,webhookURL:M,isAsync:H=!1,printLog:N=!1,writeLogFile:J=!1}=B,z=[];return new Proxy(()=>{},{get:(K,Q,S)=>{return z.push({method:"get",arguments:[Q]}),S},set:(K,Q,S,Z)=>{return z.push({method:"set",arguments:[Q,S]}),Z},apply:(K,Q,S)=>{if(z.at(-1)?.arguments[0]==="execution")return z.pop(),W({scriptToken:E,webhookURL:M,isAsync:H,argv:{info:z}}).then(async(q)=>{let Y=await q.json();if(z=[],N)D(Y);if(J)await P(Y);return Y.data.result});return z.push({method:"apply",arguments:S}),Q}})},W=({scriptToken:B,webhookURL:E,isAsync:M,argv:H})=>{let N=JSON.stringify({Context:{argv:H}}),J=$.parse(E);J.base=M?"task":"sync_task";let z=$.format(J);return fetch(z,{method:"post",headers:{"Content-Type":"application/json","AirScript-Token":B},body:N})},U=(B)=>{let E=new URL("https://www.kdocs.cn/api/v3/script/task");return E.searchParams.append("task_id",B),fetch(E)},D=(B)=>{let E=B,{status:M,data:H,error:N,error_details:J}=E;console.log("status:",M);let z=H.logs.at(-1).unix_time-H.logs[1].unix_time;if(console.log("runtime:",z),N)console.error(J.name),console.error(J.msg),console.error(J.stack);let X=H.logs.filter((K)=>K.filename!=="<system>");if(X.length!==0){console.log("log:");for(let K of X)console[K.level](...K.args)}return console.log("result:"),console.log(H.result),E},P=(B)=>{return G("./wpsjs.log.json",JSON.stringify(B,void 0,2))};export{P as writeLogFileToCurrent,U as queryTask,O as initRemoteCallWpsjsGlobal,W as execution};
1
+ import{writeFile as V}from"fs/promises";import v from"path";var Q=Symbol("info"),G=Symbol("then"),I=(J)=>{let{scriptToken:B,webhookURL:X,isAsync:K=!1,printLog:Y=!1,writeLogFile:M=!1}=J,N={get(E,H,$){let Z=E[Q]??=[],z=()=>{};if(z[G]=!1,z[Q]=[...Z],H!=="then")z[Q].push({method:"get",arguments:[H]});else z[G]=!0;return new Proxy(z,N)},set(E,H,$,Z){let q=[...E[Q]??=[],{method:"set",arguments:[H,$]}];return U=D({scriptToken:B,webhookURL:X,isAsync:K,argv:{info:q}}).then(async(x)=>{let W=await x.json();if(Y)_(W);if(M)await P(W);return W?.data.result}),!0},apply(E,H,$){if(!E[G]){let Z=E[Q]??=[],z=()=>{};return z[G]=!1,z[Q]=[...Z,{method:"apply",arguments:$}],new Proxy(z,N)}else{let Z=E[Q];return D({scriptToken:B,webhookURL:X,isAsync:K,argv:{info:Z}}).then(async(z)=>{let q=await z.json();if(Y)_(q);if(M)await P(q);return q?.data.result}).then(...$)}}};return new Proxy(()=>{},N)},D=({scriptToken:J,webhookURL:B,isAsync:X,argv:K})=>{let Y=JSON.stringify({Context:{argv:K}}),M=v.parse(B);M.base=X?"task":"sync_task";let N=v.format(M);return fetch(N,{method:"post",headers:{"Content-Type":"application/json","AirScript-Token":J},body:Y})},U=null,j=async()=>U,O=(J)=>{let B=new URL("https://www.kdocs.cn/api/v3/script/task");return B.searchParams.append("task_id",J),fetch(B)},_=(J)=>{let B=J,{status:X,data:K,error:Y,error_details:M}=B;console.log("status:",X);let N=K.logs.at(-1).unix_time-K.logs[1].unix_time;if(console.log("runtime:",N),Y)console.error(M.name),console.error(M.msg),console.error(M.stack);let E=K.logs.filter((H)=>H.filename!=="<system>");if(E.length!==0){console.log("log:");for(let H of E)console[H.level](...H.args)}return console.log("result:"),console.log(K.result),B},P=(J)=>{return V("./wpsjs.log.json",JSON.stringify(J,void 0,2))};export{P as writeLogFileToCurrent,j as setValueOk,O as queryTask,I as initRemoteCallWpsjsGlobal,D as execution};
package/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { InfoItem, RemoteCallWpsjsGlobalReturn, WithExecutionWpsjsGlobal } from './types'
1
+ import type { InfoItem, RemoteCallWpsjsGlobalReturn, WpsjsGlobalApi } from './types'
2
2
  import { writeFile } from 'fs/promises'
3
3
  import path from 'path'
4
4
 
@@ -15,43 +15,64 @@ interface Config {
15
15
  writeLogFile?: boolean
16
16
  }
17
17
 
18
+ const infoSymbol = Symbol('info')
19
+ const isThenSymbol = Symbol('then')
20
+
18
21
  const initRemoteCallWpsjsGlobal = (config: Config) => {
19
22
  const { scriptToken, webhookURL, isAsync = false, printLog = false, writeLogFile = false, } = config
20
- let info: InfoItem[] = []
21
- const handle: ProxyHandler<() => void> = {
22
- get: (_target, p: string, receiver) => {
23
- info.push({ method: 'get', arguments: [p] })
24
- return receiver
23
+ type ProxyTarget = { (): void;[infoSymbol]: InfoItem[], [isThenSymbol]: boolean }
24
+
25
+ const handle: ProxyHandler<ProxyTarget> = {
26
+ get(target, p: string, _receiver) {
27
+ const oldInfo = target[infoSymbol] ??= []
28
+ const func: ProxyTarget = () => { }
29
+ func[isThenSymbol] = false
30
+ func[infoSymbol] = [...oldInfo]
31
+ if (p !== 'then')
32
+ func[infoSymbol].push({ method: 'get', arguments: [p] })
33
+ else
34
+ func[isThenSymbol] = true
35
+ return new Proxy(func, handle)
25
36
  },
26
- set: (_target, p: string, newValue, receiver) => {
27
- info.push({ method: 'set', arguments: [p, newValue] })
28
- return receiver
37
+ set(target, p, newValue, _receiver) {
38
+ const oldInfo = target[infoSymbol] ??= []
39
+ const info = [...oldInfo, { method: 'set', arguments: [p, newValue] }]
40
+ setValuePromise = execution({ scriptToken, webhookURL, isAsync, argv: { info } })
41
+ .then(async (response) => {
42
+ const responseObj = await response.json()
43
+ if (printLog) printInfo(responseObj)
44
+ if (writeLogFile) await writeLogFileToCurrent(responseObj)
45
+ return responseObj?.['data']['result']
46
+ })
47
+ return true
29
48
  },
30
- apply: (_target, thisArg, argArray) => {
31
- const lastInfo = info.at(-1)
32
- if (lastInfo?.arguments[0] === 'execution') {
33
- info.pop() /* 删除 execution的调用信息 */
49
+ apply(target, _thisArg, argArray) {
50
+ if (!target[isThenSymbol]) {
51
+ const oldInfo = target[infoSymbol] ??= []
52
+ const func: ProxyTarget = () => { }
53
+ func[isThenSymbol] = false
54
+ func[infoSymbol] = [...oldInfo, { method: 'apply', arguments: argArray }]
55
+ return new Proxy(func, handle)
56
+ } else {
57
+ const info = target[infoSymbol]
34
58
  return execution({ scriptToken, webhookURL, isAsync, argv: { info } })
35
59
  .then(async (response) => {
36
60
  const responseObj = await response.json()
37
- info = [] /* 执行结束,清空调用 */
38
61
  if (printLog) printInfo(responseObj)
39
-
40
62
  if (writeLogFile) await writeLogFileToCurrent(responseObj)
41
- return responseObj['data']['result']
63
+ return responseObj?.['data']['result']
42
64
  })
65
+ .then(...argArray)
43
66
  }
44
- info.push({ method: 'apply', arguments: argArray })
45
- return thisArg
46
67
  },
47
68
  }
48
- return new Proxy(() => { }, handle) as unknown as WithExecutionWpsjsGlobal
69
+ return new Proxy(() => { }, handle) as unknown as WpsjsGlobalApi
49
70
  }
50
71
 
51
72
  type ExecutionConfig = Pick<Config, 'scriptToken' | 'webhookURL' | 'isAsync'> & { argv?: Record<string | number, any> }
52
73
 
53
74
  const execution = ({ scriptToken, webhookURL, isAsync, argv }: ExecutionConfig) => {
54
- /* 获取请求信息 */
75
+ /* 请求信息 */
55
76
  const data = JSON.stringify({ Context: { argv, } })
56
77
  /* 根据是否同步返回不同的url */
57
78
  const parsedPath = path.parse(webhookURL)
@@ -67,6 +88,10 @@ const execution = ({ scriptToken, webhookURL, isAsync, argv }: ExecutionConfig)
67
88
  })
68
89
  }
69
90
 
91
+ let setValuePromise: any = null
92
+ /* 远程调用的赋值操作返回的promise */
93
+ const setValueOk = async () => setValuePromise
94
+
70
95
  const queryTask = (id: string) => {
71
96
  const url = new URL('https://www.kdocs.cn/api/v3/script/task')
72
97
  url.searchParams.append('task_id', id)
@@ -100,11 +125,10 @@ const writeLogFileToCurrent = (data: object) => {
100
125
  return writeFile('./wpsjs.log.json', JSON.stringify((data), undefined, 2))
101
126
  }
102
127
 
103
- export type * from './types'
104
-
105
128
  export {
106
129
  execution,
107
130
  initRemoteCallWpsjsGlobal,
108
131
  queryTask,
132
+ setValueOk,
109
133
  writeLogFileToCurrent,
110
134
  }
package/package.json CHANGED
@@ -1,29 +1,36 @@
1
- {
2
- "name": "tadcode-wpsjs",
3
- "version": "0.3.2",
4
- "main": "index.js",
5
- "type": "module",
6
- "scripts": {
7
- "hot": "NODE_ENV=development bun --hot ignore/index.ts",
8
- "dev": "NODE_ENV=development bun --watch index.ts",
9
- "build": "NODE_ENV=production bun build index.ts --target node --minify --outfile index.js"
10
- },
11
- "devDependencies": {
12
- "@types/bun": "latest"
13
- },
14
- "keywords": [
15
- "tadcode-wpsjs"
16
- ],
17
- "exports": {
18
- ".": {
19
- "import": "./index.js",
20
- "types": "./index.ts"
21
- },
22
- "./types": {
23
- "types": "./types/index.d.ts"
24
- },
25
- "./types/DB_Application": {
26
- "types": "./types/DB_Application.d.ts"
27
- }
28
- }
29
- }
1
+ {
2
+ "name": "tadcode-wpsjs",
3
+ "version": "1.1.0",
4
+ "main": "index.js",
5
+ "type": "module",
6
+ "scripts": {
7
+ "hot": "NODE_ENV=development bun --hot ignore/index.ts",
8
+ "dev": "NODE_ENV=development bun --watch index.ts",
9
+ "build-main": "NODE_ENV=production bun build index.ts --target node --minify --outfile index.js",
10
+ "build-remotecode": "NODE_ENV=production bun build remoteCode/index.js --target browser --minify --outfile remoteCode/index.min.js"
11
+ },
12
+ "devDependencies": {
13
+ "@types/bun": "latest"
14
+ },
15
+ "keywords": [
16
+ "tadcode-wpsjs"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "import": "./index.js",
21
+ "types": "./index.ts"
22
+ },
23
+ "./types": {
24
+ "types": "./types/index.d.ts"
25
+ },
26
+ "./types/DB_Application": {
27
+ "types": "./types/DB_Application.d.ts"
28
+ },
29
+ "./types/KSDrive": {
30
+ "types": "./types/KSDrive.d.ts"
31
+ },
32
+ "./types/KSheet_Application": {
33
+ "types": "./types/KSheet_Application.d.ts"
34
+ }
35
+ }
36
+ }
@@ -0,0 +1 @@
1
+ var{info:a}=Context.argv,s=void 0,e=globalThis;for(let t of a)switch(t.method){case"get":{s=e;let[r]=t.arguments;e=Reflect.get(e,r)}break;case"set":{let[r,o]=t.arguments;e=Reflect.set(e,r,o)}break;case"apply":e=Reflect.apply(e,s,t.arguments);break;default:throw Error("method must be get or apply")}return e;
@@ -4,6 +4,31 @@ import type DBField from './DB_Application_Field'
4
4
  import type DBRecord from './DB_Application_Record'
5
5
  import type DBSelection from './DB_Application_Selection'
6
6
 
7
+ interface DBUserInfo {
8
+ id: string
9
+ name: string
10
+ }
11
+
12
+ interface DBFileInfo {
13
+ id: string
14
+ name: string
15
+ officeType: string
16
+ creator: {
17
+ id: string
18
+ name: string
19
+ avatar_url: string
20
+ logined: boolean
21
+ attrs: {
22
+ real_userid: string
23
+ }
24
+ real_id: string
25
+ }
26
+ size: number
27
+ groupId: string
28
+ docType: number
29
+ version: number
30
+ }
31
+
7
32
  export type * from './DB_Application_Sheet'
8
33
  export type * from './DB_Application_View'
9
34
  export type * from './DB_Application_Field'
@@ -18,5 +43,7 @@ export default interface DB_Application {
18
43
  Field: DBField
19
44
  Record: DBRecord
20
45
  Selection: DBSelection
46
+ UserInfo: DBUserInfo
47
+ FileInfo: DBFileInfo
21
48
  }
22
49
 
@@ -1,22 +1,22 @@
1
- import type { RecordItem } from './DB_Application_Record'
2
-
3
- interface ActiveView {
4
- "sheetId": number
5
- "viewId": string
6
- "name": string
7
- "type": string
8
- }
9
-
10
- interface ActiveSheet {
11
- "sheetId": number
12
- "name": string
13
- "description": string
14
- }
15
-
16
- export type { ActiveView, ActiveSheet }
17
-
18
- export default interface DBSelection {
19
- GetActiveView(): ActiveView
20
- GetSelectionRecords(): RecordItem[]
21
- GetActiveSheet(): ActiveSheet
22
- }
1
+ import type { RecordItem } from './DB_Application_Record'
2
+
3
+ interface ActiveView {
4
+ "sheetId": number
5
+ "viewId": string
6
+ "name": string
7
+ "type": string
8
+ }
9
+
10
+ interface ActiveSheet {
11
+ "sheetId": number
12
+ "name": string
13
+ "description": string
14
+ }
15
+
16
+ export type { ActiveView, ActiveSheet }
17
+
18
+ export default interface DBSelection {
19
+ GetActiveView(): ActiveView
20
+ GetSelectionRecords(): RecordItem[]
21
+ GetActiveSheet(): ActiveSheet
22
+ }
@@ -1,13 +1,33 @@
1
1
  import type DB_Application from './DB_Application'
2
2
  import type KSheet_Application from './KSheet_Application'
3
3
 
4
+ interface FileType {
5
+ /**智能文档 */
6
+ AP: 'o'
7
+ /**智能表格 */
8
+ KSheet: 'k'
9
+ /**表格 */
10
+ ET: 's'
11
+ /**多维表 */
12
+ DB: 'd'
13
+ }
14
+
15
+ /**
16
+ * 文件类型
17
+ * - 'o': 智能文档
18
+ * - 'k': 智能表格
19
+ * - 's': 表格
20
+ * - 'd': 多维表
21
+ */
22
+ type FileTypeValue = FileType[keyof FileType]
23
+
4
24
  interface CreateOptions {
5
25
  /**是 新文件的文件名 */
6
26
  name: string
7
27
  /**否 新文件的文件目录 */
8
- dirUrl: string
28
+ dirUrl?: string
9
29
  /**否 将目标文件另存为新文件 */
10
- source: string
30
+ source?: string
11
31
  }
12
32
 
13
33
  interface FilesInfo {
@@ -26,25 +46,17 @@ interface FileInfo {
26
46
  updateTime: number
27
47
  }
28
48
 
29
- export default interface KSDrive {
30
- FileType: {
31
- /**智能文档 */
32
- AP: 'o'
33
- /**智能表格 */
34
- KSheet: 'k'
35
- /**表格 */
36
- ET: 's'
37
- /**多维表 */
38
- DB: 'd'
39
- }
49
+ export type { FileType, FileTypeValue, CreateOptions, FilesInfo, FileInfo }
40
50
 
51
+ export default interface KSDrive {
52
+ FileType: FileType
41
53
  /**
42
54
  * 创建文件
43
55
  * @param type 新文件的类型
44
56
  * @param createOptions 新文件的参数选项
45
- * @returns {string} 新文件url
57
+ * @returns 新文件url
46
58
  */
47
- createFile(type: string, createOptions: createOptions): string
59
+ createFile(type: FileTypeValue, createOptions: CreateOptions): string
48
60
 
49
61
  openFile(url: string): {
50
62
  Application: KSheet_Application & DB_Application
@@ -1,11 +1,11 @@
1
- interface Range {
1
+ interface KSheetRange {
2
2
  Value2: any
3
3
  Formula: any
4
- Resize(RowSize: number, ColumnSize?: number): Range
4
+ Resize(RowSize: number, ColumnSize?: number): KSheetRange
5
5
  }
6
6
 
7
- interface Sheet {
8
- UsedRange: Range
7
+ interface KSheetSheet {
8
+ UsedRange: KSheetRange
9
9
  /**
10
10
  * 获取一个单元格或单元格区域,返回一个 Range 对象
11
11
  * @paramaddress — 地址,可以是单元格地址或者选区范围范围地址
@@ -17,13 +17,15 @@ interface Sheet {
17
17
  * // 修改当前活动工作表D2单元格的内容
18
18
  * sheet.Range('D2').Value = 'this is D2'
19
19
  */
20
- Range(address: string): Range
20
+ Range(address: string): KSheetRange
21
21
  }
22
22
 
23
+ export type { KSheetRange, KSheetSheet }
24
+
23
25
  export default interface KSheet_Application {
24
- ActiveSheet: Sheet
26
+ ActiveSheet: KSheetSheet
25
27
  Sheets: {
26
- Item(index: number | string): Sheet
28
+ Item(index: number | string): KSheetSheet
27
29
  }
28
- Range(index: string): Range
30
+ Range(index: string): KSheetRange
29
31
  }
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { WithExecution } from './type-tools'
1
+ import type { WithPromise } from './type-tools'
2
2
  import type DB_Application from './DB_Application'
3
3
  import type KSheet_Application from './KSheet_Application'
4
4
  import type KSDrive from './KSDrive'
@@ -8,40 +8,56 @@ interface WpsjsGlobal {
8
8
  Application: KSheet_Application & DB_Application
9
9
  }
10
10
 
11
- type WithExecutionWpsjsGlobal = WithExecution<WpsjsGlobal>
11
+ type WpsjsGlobalApi = WithPromise<WpsjsGlobal>
12
12
 
13
13
  interface InfoItem {
14
14
  method: keyof typeof Reflect
15
15
  arguments: string[]
16
16
  }
17
17
 
18
+ /* 基本 */
18
19
  interface RemoteCallWpsjsGlobalReturn {
19
- "data": {
20
- "logs": {
21
- "filename": string
22
- "timestamp": string
23
- "unix_time": number
24
- "level": 'info' | 'error' | 'warn'
25
- "args": string[]
20
+ data: {
21
+ logs: {
22
+ filename: string
23
+ timestamp: string
24
+ unix_time: number
25
+ level: 'info' | 'error' | 'warn'
26
+ args: string[]
26
27
  }[]
27
- "result": unknown
28
- "task_id": string
28
+ result: unknown
29
+ task_id: string
29
30
  }
30
- "error": string
31
- "error_details": {
32
- "name": string
33
- "msg": string
34
- "stack": string[]
35
- "unix_time": number
31
+ error: string
32
+ error_details: {
33
+ name: string
34
+ msg: string
35
+ stack: string[]
36
+ unix_time: number
36
37
  }
37
- "status": "finished"
38
- "task_id": string
39
- "task_type": string
38
+ status: 'finished'
39
+ task_id: string
40
+ task_type: string
41
+ }
42
+
43
+ /* token 过期 */
44
+ interface RemoteCallWpsjsGlobalReturn {
45
+ errno: 10000
46
+ msg: string
47
+ reason: string
48
+ result: ApiTokenExpired
40
49
  }
41
50
 
42
51
  export {
43
52
  WpsjsGlobal,
44
- WithExecutionWpsjsGlobal,
53
+ WpsjsGlobalApi,
45
54
  InfoItem,
46
55
  RemoteCallWpsjsGlobalReturn,
47
56
  }
57
+
58
+ export type * from './DB_Application'
59
+ export type { default as DB_Application } from './DB_Application'
60
+ export type * from './KSDrive'
61
+ export type { default as KSDrive } from './KSDrive'
62
+ export type * from './KSheet_Application'
63
+ export type { default as KSheet_Application } from './KSheet_Application'
@@ -24,10 +24,27 @@ type DeepPartial<T> = T extends object
24
24
  type DistributiveOmit<T, K extends PropertyKey> =
25
25
  T extends any ? Omit<T, K> : never
26
26
 
27
+ /**根据给的对象,添加promise方法 */
28
+ type WithPromise<T> = T extends (...args: infer A) => infer R ?
29
+ ((...args: A) => WithPromise<R>) & Promise<T> :
30
+ T extends Array<infer U> ?
31
+ Array<WithPromise<U>> & Promise<T> :
32
+ T extends object ?
33
+ { [K in keyof T]: WithPromise<T[K]> } & Promise<T> :
34
+ T extends boolean ?
35
+ Promise<boolean> :
36
+ T extends number ?
37
+ Promise<number> :
38
+ T extends string ?
39
+ Promise<string>
40
+ : T & Promise<T>
41
+
42
+ // 搞定!🎉
27
43
  export type {
28
44
  WithExecution,
29
45
  MakePropertyOptional,
30
46
  PickModify,
31
47
  DeepPartial,
32
48
  DistributiveOmit,
49
+ WithPromise,
33
50
  }