From 011db7a820fcafa1ecdc5f45beaa1f8a8e5c7571 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Wed, 8 Nov 2023 12:30:53 +0800 Subject: [PATCH] fix(napi-derive): async task optional output type --- 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 -> 4139 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 c9d4de084b..40f3701d25 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 0ac18d85f9..e6f3d1f535 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 43e377067d..aaacefb022 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..331ad80ee7918825c0774a9380cf116ec4931a3c 100644 GIT binary patch delta 4108 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 K!c?caJ^%phpXCPt delta 4125 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 b1TP7;%!PjrzkhJQWAgq7+#Kq$ay|e6ZaC@a diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index 782b9ca956..b26405f481 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -236,6 +236,8 @@ export function asyncPlus100(p: Promise): 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 c4e9b0503d..0b23f986f0 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 {}) +}