From e930a6aab38043e3b47838df3253c8781cb2a997 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 8 Nov 2023 20:06:27 +0800 Subject: [PATCH] fix(napi-derive): async task optional output type (#1796) --- crates/backend/src/typegen.rs | 1 + crates/backend/src/typegen/struct.rs | 8 +++++-- .../__snapshots__/typegen.spec.ts.md | 2 ++ .../__snapshots__/typegen.spec.ts.snap | Bin 4132 -> 4138 bytes examples/napi/index.d.ts | 2 ++ examples/napi/src/task.rs | 21 ++++++++++++++++++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index c9d4de08..40f3701d 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -263,6 +263,7 @@ fn is_ts_function_type_notation(ty: &Type) -> bool { } } +// return (type, is_optional, is_variadic) pub fn ty_to_ts_type( ty: &Type, is_return_ty: bool, diff --git a/crates/backend/src/typegen/struct.rs b/crates/backend/src/typegen/struct.rs index 0ac18d85..e6f3d1f5 100644 --- a/crates/backend/src/typegen/struct.rs +++ b/crates/backend/src/typegen/struct.rs @@ -36,13 +36,17 @@ impl ToTypeDef for NapiImpl { fn to_type_def(&self) -> Option { if let Some(output_type) = &self.task_output_type { TASK_STRUCTS.with(|t| { - let resolved_type = ty_to_ts_type(output_type, false, true, false).0; + let (resolved_type, is_optional, _) = ty_to_ts_type(output_type, false, true, false); t.borrow_mut().insert( self.name.to_string(), if resolved_type == "undefined" { "void".to_owned() } else { - resolved_type + if is_optional { + format!("{} | null", resolved_type) + } else { + resolved_type + } }, ); }); diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md index 43e37706..4bb95143 100644 --- a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md @@ -246,6 +246,8 @@ Generated by [AVA](https://avajs.dev). ␊ export function asyncReduceBuffer(buf: Buffer): Promise␊ ␊ + export function asyncTaskOptionalReturn(): Promise␊ + ␊ export function asyncTaskVoidReturn(): Promise␊ ␊ export interface B {␊ diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap index 522fda1a4822e4167976a582842d15b57baa43cd..30c3aa3fd81e568d3d2082f56315a1b9a10e69fe 100644 GIT binary patch delta 4004 zcmV;V4_ol0AgUmLK~_N^Q*L2!b7*gLAa*kf0|1LN%F<9fZbPT+^9oyqRJChxPkm&i zip*!)&g`Gf;D{fK2mk;800003wOj9U+_n)<+v#-1-}(lqI~`M=vtr2}k9%XuBgv8@ z$C5m{bDWIhiFqXM4i=BN5TNCYtC{8v`ng{^$rJVwx{E)5BuIkf$#Ij|A;I0n0$BX^ z4{*OsCkc-(#LvG{$z(!5{7uYxp2TEEQ<{a6l89#+jUmzgtjMifL)B1g z%2W1ZPKj78COlD}Uw=I`uWyEA3{6)zu0Vm?H^^=BHsYy}SsqEAy(N4p8BfWSXXLGJ zeG9^W%vnYS36lgyPm@>>$;pJ0Wj;w*G(a(2&S`dk$pj@boDsHI0%=M@K^*Z&_t)1j zb1ZOLH{RU9p;rdJm$F5esKJ4n0hKAH;M8Y;X^0j`rw2qScb&)5M-2uD8u`d=hmAW0(g!vjiBN3X}Zxw%;xHfZ{U&(y#-+}YQ?eMK`$Lii*20u-5t8B8F}KucK2 z;uXdQhMGoHXf8PqB{BOCtc!{$T*AIFJ1|*)4K>;Kuit#U`ttkX&6^)}!&NbqjLJMq z&(IbR(2!6!P}B3}70ky$E+k(ZI2Hlq`z*tu@b@&!SWJ)8n7wCl9wvL)>?}P|1`wn? zgXJBs?34{GeN0nq{g~P>S61ZJ4WEgl8c*mngjI9&P=@c?2E6L!PxHluW;Hu@DF+o` z!VOQiyqJR{o*goLQ~kLT+xdhT$yGu}a|(9((U@$OCsfTfd_ITg=S)bDU<4@SwEUxy z!@uJdTkly2(^XYN-8G`|i%`z7cQZNFj-LrFU`Gq`2^VeB16I!Du#of*lUoBL2Svsg z0K1PglZ68y0fm#M10n%ElgR@}e-C;KEyC4=o>Ce=9+C;?2@O+dov5`Ml9v#UJlxB& zaOK$#j?zzHh0QXTQ>1&T5^5s|K)x%yLakk@<9!TeYmC0yhffA9B41<%B_1Bqwi9AZ#O3)|?}`bfLv4WTj1TsN61d4clK zT6ROwDNEml<2-{5uLJ#=IEGF_2uRPS!TT`DDJD}FDZflNT)0I4dZ3n`tazT06r~fX z#Qz0i>wo=P36)cNc^)oRgyQI-cl=2xE)IC2L(f7V^~x*I3^M`KMgI z%9zBoQZ3MRBaasMVqAH(uQQc0nrzJsS*MYQkQ|ugF?J$lL;u);-aLiO8giD{!0<+M zaWvaVhM5ekhz#^vHY&kYY#z$mxdUFw0(u?se=m|;Y~8&ZEE^1Ki#Vro9#QWstS4X$F3zsTxpHDbgVz{nmxyn`44dp| zoVy+i*jFn)3A3&Rp0F8k>}gBZFUpej|*Kj<>cS2J2BixZh6*q1ej@_xB(~ zM;i?$%u&YJZIjb)ZjDva4Zg`bFq8FD*JMRul1#$r9zw5y6*}GxEX8rU%mL^F1s!8p z(UN9RaQk5?Q~B?cpa&FxP8?|z)R5<(TCHH>DWQ0~dd}0C$5A)~+uYoQ&LA=a+`yeMLK)>}k_Wu+X_ehRx~>x88_1l&w7 zIJR!+|8+5r`3XxBh+eB~HD^&{JcT&vJyq;%p(;!ClQ>J@z!sZ->o-|>8in#Xu%=sq zXaxzD-i4_>iD+Wu~&~`mfBz@PMS)Yi^-{pYv1J+ zapTpJ#(L5=DihX!#t7n(lB-@ih~TTvvN3VS(=_DL?dny1u!(4g925e`wS?tWDt@$~ z>0TLx3{+KVrc(Q|icEa)uEgqUg33Gf>0u|`5$57lM6M|tHcXMf<2l%$I?Ms43w0hR zBweaQAS_9TDdxt?%mGn&F7yaC-P&{+JnHJyX}&nbH}qJ4XDP+#5yMCbkl=A!Jp!g; z`#pR)!u))P+{fn;`v8v*@bM5!SMc%>Urw2l^LNEeQxtjE>j9MlkS)qw9Pn7B=M}gt zJu0G%unBQy&<@@po_uUxJRQUeCQsEGwZLTcSW?eUeYTz)9__t+KK|k0Y&33%Nyy^p zvM{_`#^n`6>il? zEoB64?zPnkYPlH8>D^kmvON&D4}T6iu-su*v9K;z)v9Ms&fg|Mqug0mwUXLobtYkl zi={MYDa}5BV9by2Z3loOl?~T1-%~b$*glF_khW)kfhBc%P9qAwIW`F%y247XHz3p` zdaX+Vh-Na9j${mv&n{y(plZZ|ok0)qtGQaMr^1&}^U&tTI;IB1JWco{Q~-?Cdp;#I z)!?N)fdmyj9uUKn@+^L2;oi2;zK2XfDRS5E zQ`N;9d&_1&%r1nkT;th|DbVQqH%THOm;;S}^!I~MTF|(OM^fGCy0>0` z>09vf7@!4&bq%t!=-ms`P8Ge@%jb}*4;)(5_nr^vs_MEPmC|n8;Jx}e>e`c#+L_qH>3(Byv29@6=5Trvwy#5NhmGl@}SY8bi%DhbyL7il%AAsCe9P_ptkR z718@A{dAsfx(rhmwL7C_k_$++%(0_7py_aMOI=JmPIXLcaj<~p_BynQ&5e)4Yog#t zJ{B{D=^dFu_NmUMcgX9Tf@U$jgDY|K4Y~3K3|L*mP^Y=CETR>b@;RW$cBe0YXDvg# zF44HoQ?J8TxE@-sq|bw}~+DWF^%>*^AQ+ z*JoZh^#4AUBo!SYHl?7tnw84e>G31M65bHK`pfjHlXsR$jC--#u8X93mce>yr^2?7DDiS@+e+XW^Io zZj=;k+P4O5Eni-6ncF$et&cwao~U1H^d6?W;OP}oj%qP_u<3*!F_d%W+$kCf*R(3Al8Z{0x0n4A3=D8ZR6F! zo*SNC#(UrPYI5b*z|=%&f-UDbybxA#_utk zL44|5Rw3&5q?LqV@A>i5)04x~u`_h+36$R2epn9QRo0yoyd>B%7ydc?;lcfm$@?FP K**5#NJ^%oJ7`ZI~ delta 4014 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: Promise export function asyncReduceBuffer(buf: Buffer): Promise +export function asyncTaskOptionalReturn(): Promise + export function asyncTaskVoidReturn(): Promise export interface B { diff --git a/examples/napi/src/task.rs b/examples/napi/src/task.rs index c4e9b050..0b23f986 100644 --- a/examples/napi/src/task.rs +++ b/examples/napi/src/task.rs @@ -49,3 +49,24 @@ impl Task for AsyncTaskVoidReturn { fn async_task_void_return() -> AsyncTask { AsyncTask::new(AsyncTaskVoidReturn {}) } + +struct AsyncTaskOptionalReturn {} + +#[napi] +impl Task for AsyncTaskOptionalReturn { + type JsValue = Option; + type Output = (); + + fn compute(&mut self) -> Result { + Ok(()) + } + + fn resolve(&mut self, _env: Env, _: Self::Output) -> Result { + Ok(None) + } +} + +#[napi] +fn async_task_optional_return() -> AsyncTask { + AsyncTask::new(AsyncTaskOptionalReturn {}) +}