TypeScript 配置

以 Markdown 格式查看

您可以在 generators.yml 中自定义 TypeScript SDK 生成器的行为:

generators.yml
1groups:
2 ts-sdk:
3 generators:
4 - name: fernapi/fern-typescript-sdk
5 version: 3.69.0
6 config:
7 namespaceExport: AcmePayments
8 noSerdeLayer: false
9 generateSubpackageExports: true
allowExtraFields
boolean

允许对象模式中未定义的字段。这仅适用于序列化。

更多信息请参见 TypeScript 序列化层

defaultTimeoutInSeconds
number | 'infinity'

网络请求的默认超时时间。在生成的客户端中,可以在请求级别覆盖此设置。

enableInlineTypes
booleanDefaults to true

启用后,内联模式将在 TypeScript 中生成为嵌套类型。 这会产生更清晰的类型名称和更直观的开发者体验。

enableInlineTypes: false

1// MyRootType.ts
2import * as MySdk from "...";
3
4export interface MyRootType {
5 foo: MySdk.MyRootTypeFoo;
6}
7
8// MyRootTypeFoo.ts
9import * as MySdk from "...";
10
11export interface MyRootTypeFoo {
12 bar: MySdk.MyRootTypeFooBar;
13}
14
15// MyRootTypeFooBar.ts
16import * as MySdk from "...";
17
18export interface MyRootTypeFooBar {}

enableInlineTypes: true

1// MyRootType.ts
2import * as MySdk from "...";
3
4export interface MyRootType {
5 foo: MyRootType.Foo;
6}
7
8export namespace MyRootType {
9 export interface Foo {
10 bar: Foo.Bar;
11 }
12
13 export namespace Foo {
14 export interface Bar {}
15 }
16}

现在用户可以按如下方式获取深度嵌套的 Bar 类型:

1import { MyRootType } from MySdk;
2
3const bar: MyRootType.Foo.Bar = {};
extraDependencies
objectDefaults to {}
专业版和企业版功能

此功能仅适用于专业版和企业版计划。如需开始使用,请联系 support@buildwithfern.com

在生成的 package.json 中指定额外的依赖项。当您向 SDK 添加需要额外依赖项的自定义代码时,这很有用。

1# generators.yml
2config:
3 extraDependencies:
4 lodash: "3.0.2"
extraDevDependencies
objectDefaults to {}
专业版和企业版功能

此功能仅适用于专业版和企业版计划。如需开始使用,请联系 support@buildwithfern.com

在生成的 package.json 中指定额外的开发依赖项。

1# generators.yml
2config:
3 extraDevDependencies:
4 jest: "29.0.7"
仅在发布到 Github 时适用。
extraPeerDependencies
object

在生成的 package.json 中指定额外的对等依赖项:

1# generators.yml
2config:
3 extraPeerDependencies:
4 react: ">=16.8.0 <19.0.0"
5 "react-dom": ">=16.8.0 <19.0.0"
extraPeerDependenciesMeta
object

在生成的 package.json 中指定额外的对等依赖项元字段:

1# generators.yml
2config:
3 extraPeerDependencies:
4 react: ">=16.8.0 <19.0.0"
5 "react-dom": ">=16.8.0 <19.0.0"
fetchSupport
'node-fetch' | 'native'

选择是否要包含 node-fetch 以支持 Node.js 18 之前的版本,或选择 native 来使用 Node.js 18 及更高版本中可用的原生 fetch API。

fileResponseType
'stream' | 'binary-response'

更改为二进制 HTTP 响应返回给用户的响应类型:

  • stream:返回流。请参见 streamType,它控制返回的流类型。
  • binary-response:返回 BinaryResponse 类型,允许用户选择如何使用二进制 HTTP 响应。 以下是用户与 BinaryResponse 交互的方式:
1const response = await client.getFile(...);
2const stream = response.stream();
3// const arrayBuffer = await response.arrayBuffer();
4// const blob = await response.blob();
5// const bytes = await response.bytes();
6const bodyUsed = response.bodyUsed;
formDataSupport
'Node16' | 'Node18'

选择是否要支持 Node.js 16 及以上版本(Node16),或 Node.js 18 及以上版本(Node18)。

  • Node16 使用多个依赖项来支持多部分表单,包括 form-dataformdata-nodeform-data-encoder
  • Node18 使用原生 FormData API,并接受更广泛的文件上传类型,如 BufferFileBlobReadableReadableStreamArrayBufferUint8Array
generateSubpackageExports
booleanDefaults to false

生成子包导出,允许用户直接导入单个客户端,而不是导入整个 SDK。这使 JavaScript 打包器能够摇树优化未使用的代码,显著减少打包大小。

1import { BarClient } from '@acme/sdk/foo/bar';
2// 仅导入 Bar 子包
3
4const client = new BarClient({...});

启用此选项时,子包导出也会在生成的 README.md 中记录。

includeContentHeadersOnFileDownloadResponse
boolean

包含二进制响应中的内容类型和内容长度。用户将收到以下类型的对象:

1{
2 data: <BINARY_RESPONSE_TYPE>;
3 contentLengthInBytes?: number;
4 contentType?: string;
5}

<BINARY_RESPONSE_TYPE>core.BinaryResponse 或流,取决于 fileResponseType 设置。

includeCredentialsOnCrossOriginRequests
booleanDefaults to false

启用后,在进行网络请求时会将 withCredentials 设置为 true

includeOtherInUnionTypes
boolean
includeUtilsOnUnionMembers
boolean
inlineFileProperties
booleanDefaults to true

将文件上传属性生成为内联请求属性(而不是位置参数)。

inlineFileProperties: false

1/**
2 * @param {File | fs.ReadStream} file
3 * @param {File[] | fs.ReadStream[]} fileList
4 * @param {File | fs.ReadStream | undefined} maybeFile
5 * @param {File[] | fs.ReadStream[] | undefined} maybeFileList
6 * @param {Acme.MyRequest} request
7 * @param {Service.RequestOptions} requestOptions - Request-specific configuration.
8 *
9 * @example
10 * await client.service.post(fs.createReadStream("/path/to/your/file"), [fs.createReadStream("/path/to/your/file")], fs.createReadStream("/path/to/your/file"), [fs.createReadStream("/path/to/your/file")], {})
11 */
12public async post(
13 file: File | fs.ReadStream,
14 fileList: File[] | fs.ReadStream[],
15 maybeFile: File | fs.ReadStream | undefined,
16 maybeFileList: File[] | fs.ReadStream[] | undefined,
17 request: Acme.MyRequest,
18 requestOptions?: Acme.RequestOptions
19): Promise<void> {
20 ...
21}

inlineFileProperties: true

1/**
2 * @param {Acme.MyRequest} request
3 * @param {Service.RequestOptions} requestOptions - Request-specific configuration.
4 *
5 * @example
6 * await client.service.post({
7 * file: fs.createReadStream("/path/to/your/file"),
8 * fileList: [fs.createReadStream("/path/to/your/file")]
9 * })
10 */
11public async post(
12 request: Acme.MyRequest,
13 requestOptions?: Service.RequestOptions
14): Promise<void> {
15 ...
16}
inlinePathParameters
booleanDefaults to true

将路径参数内联到请求类型中。

inlinePathParameters: false

1await service.getFoo("pathParamValue", { id: "SOME_ID" });

inlinePathParameters: true

1await service.getFoo({ pathParamName: "pathParamValue", id: "SOME_ID" });
namespaceExport
string

自定义生成的 SDK 中导出的命名空间和客户端类名。必须使用 PascalCase。

默认情况下,名称来源于 API 定义中定义的组织和 API 名称:

1import { AcmeApi, AcmeApiClient } from "@acme/node";

设置 namespaceExport 会覆盖这些默认名称:

generators.yml
1config:
2 namespaceExport: AcmePayments
1import { AcmePayments, AcmePaymentsClient } from "@acme/node";
naming
string | object

自定义命名空间导出和类/类型名称。接受字符串简写或完整对象。

字符串简写 — 设置命名空间并通过 PascalCase 派生所有类名:

generators.yml
1config:
2 naming: acme
1import { acme, AcmeClient } from "acme";

对象形式 — 覆盖单个名称:

generators.yml
1config:
2 naming:
3 namespace: acme
4 client: AcmeSdkClient
5 error: AcmeSdkError
6 environment: AcmeSdkEnvironment
1import { acme, AcmeSdkClient } from "acme";
字段类型描述
namespacestring命名空间导出名称。等同于 namespaceExport
clientstring客户端类名称(默认:${PascalCase(namespace)}Client)。
errorstring通用 API 错误类名称(默认:${PascalCase(namespace)}Error)。
timeoutErrorstring超时错误类名称(默认:${PascalCase(namespace)}TimeoutError)。
environmentstring环境枚举名称(默认:${PascalCase(namespace)}Environment)。
environmentUrlsstring环境 URL 类型名称(默认:${PascalCase(namespace)}EnvironmentUrls)。
versionstring版本枚举名称(默认:${PascalCase(namespace)}Version)。

namespaceExport 仍然支持向后兼容,但 naming.namespace 优先级更高。

neverThrowErrors
booleanDefaults to false

启用后,当从服务器接收到非 200 响应时,客户端不会抛出错误。相反,响应会被包装在 ApiResponse 中。

1const response = await client.callEndpoint(...);
2if (response.ok) {
3 console.log(response.body)
4} else {
5 console.error(respons.error)
6}
noOptionalProperties
booleanDefaults to false

默认情况下,Fern 的 optional<> 属性将转换为可选的 TypeScript 属性:

1Person:
2 properties:
3 name: string
4 age: optional<integer>
1interface Person {
2 name: string;
3 age?: number;
4}

启用 noOptionalProperties 后,生成的属性永远不是可选的。相反,类型使用 | undefined 生成。因此,用户必须显式地将属性设置为值或 undefined

1interface Person {
2 name: string;
3 age: number | undefined;
4}
noSerdeLayer
booleanDefaults to true

控制是否为序列化/反序列化启用序列化层。

noSerdeLayer: false 时,生成的客户端包含自定义序列化代码,将属性名称转换为 camelCase,在运行时验证请求/响应,并支持复杂类型。

关于何时启用此选项的详细指导,请参见 TypeScript 序列化层

offsetSemantics
'item-index' | 'page-index'Defaults to item-index

控制如何为自动分页端点解释偏移参数。

  • item-index:偏移计算单个项目(例如,偏移 20 跳过前 20 个项目)。
  • page-index:偏移计算页面(例如,偏移 3 跳到第 3 页)。
omitFernHeaders
booleanDefaults to false

启用后,生成的 SDK 在 HTTP 请求中省略 X-Fern-LanguageX-Fern-SDK-NameX-Fern-SDK-Version 标头。默认情况下会包含这些标头,以帮助 API 提供商识别 SDK 流量。

outputSourceFiles
booleanDefaults to true

控制生成文件的输出格式:

  • 当为 true(默认)时:输出原始 TypeScript .ts 文件
  • 当为 false:运行 TypeScript 编译器并输出编译的 .js 文件和 .d.ts 声明文件
此选项仅在使用本地文件系统输出时适用。当发布到 GitHub 或 npm 时,此设置被忽略,文件始终会被编译。
packageJson
object

当您在 packageJson 中指定对象时,它将被合并到 package.json 文件中。这是自定义 SDK package.json 的推荐方式。

1# generators.yml
2config:
3 packageJson:
4 description: The SDK for Acme Corp's API.
5 author:
6 name: Acme Corp
7 url: https://developer.acmecorp.com
8 email: developers@acmecorp.com
9 bugs:
10 url: https://developer.acmecorp.com
11 email: developers@acmecorp.com

您也可以使用 packageJson.exports 来注册自定义子路径导出(例如 import { myHelper } from "@acme/sdk/helper")。生成器只为您的 API 定义自动生成导出条目,因此需要手动添加自定义文件——否则 Node.js 无法解析子路径导入。有关详细信息,请参见添加自定义代码

package-name
stringDefaults to null

指定用户将从中导入生成的客户端的 TypeScript 包名称。

例如,设置 package-name: "my_custom_package" 使用户能够使用 my_custom_package import Client 来导入您的客户端。

packagePath
string

指定生成的 SDK 源文件应放置的路径。

publishToJsr
boolean

将您的 SDK 发布到 JSR。启用后,生成器将生成 jsr.json 以及用于发布到 JSR 的 GitHub 工作流。

retainOriginalCasing
booleanDefaults to false

启用后,生成代码中的属性名称保留其在 API 定义中的原始大小写,而不是转换为 camelCase。

1# generators.yml
2config:
3 retainOriginalCasing: true

使用 OpenAPI 输入的示例:

1# OpenAPI schema
2components:
3 schemas:
4 User:
5 type: object
6 properties:
7 user_id:
8 type: string
9 display_name:
10 type: string

使用 retainOriginalCasing: true 生成的 TypeScript:

1export interface User {
2 user_id: string;
3 display_name: string;
4}

使用默认设置(retainOriginalCasing: false)生成的 TypeScript:

1export interface User {
2 userId: string;
3 displayName: string;
4}
generateWebSocketClients
boolean

从您的 AsyncAPI 规范生成 WebSocket 客户端。

之前名为 shouldGenerateWebsocketClients,该名称仍作为已弃用的别名被接受。

skipResponseValidation
booleanDefaults to false

默认情况下,如果服务器响应与预期类型不匹配(基于 Fern 定义中响应的建模方式),客户端将抛出错误。

如果 skipResponseValidation 设置为 true,则客户端永远不会因为响应格式错误而抛出错误。相反,客户端将使用 console.warn 记录问题并返回数据(转换为预期的响应类型)。

响应验证仅在启用序列化层(noSerdeLayer: false)时发生。序列化层默认被禁用(noSerdeLayer: true)。
streamType
'wrapper' | 'web'

更改生成的 SDK 中使用的流类型。

  • wrapper:流使用具有多个底层实现的包装器,以支持 Node.js 18 之前的版本。
  • web:流使用 Web 标准 ReadableStream

默认值是 web

treatUnknownAsAny
booleanDefaults to false
useBigInt
booleanDefaults to false

useBigInt 设置为 true 时,将使用自定义的 JSON 序列化器和反序列化器来保持 bigint 的精度,而不是使用原生的 JSON.stringifyJSON.parse 函数,后者会将 bigint 转换为数字而丢失精度。

当将 useBigInt 与我们的序列化层(noSerdeLayer: false)结合使用时,在 OpenAPI/Fern 规范中标记为 longbigint 的请求和响应属性都将始终是 bigint。 但是,当禁用序列化层(noSerdeLayer: true)时,它们将被类型化为 number | bigint。更多信息请参见 TypeScript 序列化层

以下是结合 useBigIntnoSerdeLayer 与下面的 Fern 定义时生成的类型的概述:

Fern 定义

1types:
2 ObjectWithOptionalField:
3 properties:
4 longProp: long
5 bigIntProp: bigint

TypeScript 输出

1// useBigInt: true
2// noSerdeLayer: false
3interface ObjectWithLongAndBigInt {
4 longProp: bigint;
5 bigIntProp: bigint;
6}
7
8// useBigInt: true
9// noSerdeLayer: true
10interface ObjectWithLongAndBigInt {
11 longProp: bigint | number;
12 bigIntProp: bigint | number;
13}
14
15// useBigInt: false
16// noSerdeLayer: false
17interface ObjectWithLongAndBigInt {
18 longProp: number;
19 bigIntProp: string;
20}
21
22// useBigInt: false
23// noSerdeLayer: true
24interface ObjectWithLongAndBigInt {
25 longProp: number;
26 bigIntProp: string;
27}
useBrandedStringAliases
booleanDefaults to false

useBrandedStringAliases 被禁用(默认值)时,字符串别名生成为 普通的 TypeScript 别名:

1// generated code
2
3export type MyString = string;
4
5export type OtherString = string;

启用 useBrandedStringAliases 后,字符串别名生成为品牌字符串。这使每个别名感觉像自己的类型,并改善了编译时安全性。

1# fern definition
2
3types:
4 MyString: string
5 OtherString: string
1// generated code
2
3export type MyString = string & { __MyString: void };
4export const MyString = (value: string): MyString => value as MyString;
5
6export type OtherString = string & { __OtherString: void };
7export const OtherString = (value: string): OtherString => value as OtherString;
1// consuming the generated type
2
3function printMyString(s: MyString): void {
4 console.log("MyString: " + s);
5}
6
7// doesn't compile, "foo" is not assignable to MyString
8printMyString("foo");
9
10const otherString = OtherString("other-string");
11// doesn't compile, otherString is not assignable to MyString
12printMyString(otherString);
13
14// compiles
15const myString = MyString("my-string");
16printMyString(myString);