如何在TypeScript中正确编写Node.js NAPI C扩展的.d.ts文件
Let’s walk through creating a proper .d.ts file for your Helloworld NAPI extension, based on the code snippet you shared (which expects 1 argument for the function).
Step 1: Create the Declaration File
First, make a file with the exact same name as your native extension (e.g., if your compiled extension is helloworld.node, name the declaration file helloworld.d.ts) and place it in the same directory.
Step 2: Define the Module and Function Types
The structure depends on how you exported the Helloworld function in your NAPI code. Here are the two most common scenarios:
Scenario 1: Named Export (Function is a property on the exported object)
If your NAPI init code registers Helloworld as a named export like this:
napi_value init(napi_env env, napi_value exports) { napi_status status; napi_value helloFn; status = napi_create_function(env, NULL, 0, Helloworld, NULL, &helloFn); if (status != napi_ok) return NULL; status = napi_set_named_property(env, exports, "Helloworld", helloFn); return exports; }
Your declaration file should look like this:
declare module './helloworld.node' { /** * Generates a hello greeting for the provided name * @param name The name to include in the greeting * @returns A formatted greeting string */ export function Helloworld(name: string): string; }
Scenario 2: Default Export (Function is the main module export)
If your NAPI code sets Helloworld as the default export:
napi_value init(napi_env env, napi_value exports) { napi_status status; napi_value helloFn; status = napi_create_function(env, NULL, 0, Helloworld, NULL, &helloFn); if (status != napi_ok) return NULL; status = napi_set_named_property(env, exports, "default", helloFn); return exports; }
Your declaration file would be:
declare module './helloworld.node' { /** * Generates a hello greeting for the provided name * @param name The name to include in the greeting * @returns A formatted greeting string */ function Helloworld(name: string): string; export default Helloworld; }
Step 3: Adjust Types to Match Your Actual Logic
Tweak the types to fit what your Helloworld function actually does:
- If it only logs to the console and doesn’t return a value, change the return type to
void:export function Helloworld(name: string): void; - If the argument is a number (e.g., an ID) instead of a string, update the parameter type:
export function Helloworld(userId: number): string; - If it accepts multiple arguments, add them in the order your NAPI code expects.
Step 4: Use the Extension in TypeScript
Now you can import and use your extension with full type safety:
// For named export import { Helloworld } from './helloworld.node'; // For default export import Helloworld from './helloworld.node'; const greeting = Helloworld("TypeScript"); console.log(greeting); // "Hello, TypeScript!" (assuming your C function returns this)
Key Tips
- Ensure the module path in
declare moduleexactly matches how you import the extension (e.g., if it’s a package namedmy-napi-hello, usedeclare module 'my-napi-hello'instead of a relative path). - Add JSDoc comments to your declaration file to make it easier for other developers (or future you) to understand how to use the function.
- If your extension has more complex exports (like classes or objects), you can define interfaces or custom types inside the module declaration too.
内容的提问来源于stack exchange,提问作者user9694738

