From Closed SDKs to Open Types: Contributing Type Definitions for Popular AI/Mapping SDKs
Practical guide (2026) to contribute TypeScript types for AI, mapping, and ClickHouse SDKs—Decide DT or first-party, write robust d.ts, test with tsd, and submit PRs.
Ship safer SDK integrations: close the typing gap for closed or poorly-typed SDKs
If your team spends hours troubleshooting runtime errors after integrating a mapping SDK, a ClickHouse client, or an AI mobile assistant, you’re fighting a preventable war. In 2026 the ecosystem has more closed-source and binary SDKs than ever—AI SDKs tied to large LLM providers, native mobile assistants, and high-performance DB clients like ClickHouse are booming—and many ship without first-class TypeScript types. That gap slows onboarding, increases bugs, and raises technical debt.
Why contributing type definitions matters in 2026
TypeScript adoption is mainstream across frontend, backend, and edge environments. Teams expect autocompletion, safer refactors, and compile-time guardrails. Contributing types—either via DefinitelyTyped or by adding first-party declarations—reduces friction for TypeScript adopters and increases an SDK’s adoption velocity.
Recent trends make this especially urgent:
- Apple using Google’s Gemini tech continues to reshape assistant integration patterns, creating closed or rapidly-evolving client APIs that need typed surfaces.
- Databases like ClickHouse became core OLAP engines for analytics teams after large investments and growth in 2025–2026; typed clients speed production usage and safer query composition.
- Mapping SDKs (mobile or web) are often distributed as minified binaries or closed SDKs—typing them externally helps teams integrate complex event systems and callbacks without guessing shapes. For offline and local-first mapping workflows, see Local‑First Edge Tools for Pop‑Ups and Offline Workflows.
Decide: DefinitelyTyped or first-party types?
Start by asking three questions:
- Is the SDK actively maintained and open to PRs? If yes, prefer first-party types in the repository (
index.d.tsortypesfield). - Does the package already publish types under
@types/on npm? If not and upstream is closed/offline, DefinitelyTyped is a fast community route. - Are you comfortable maintaining the types? DefinitelyTyped moves community maintenance to the repo; first-party types typically stay with the vendor.
Tradeoffs at a glance:
- First-party types: better alignment with versioning, fewer compatibility hoops, and greater visibility to users. Requires collaboration with maintainers and matching license compatibility.
- DefinitelyTyped: quick to publish types for closed or slow-moving packages. Community-driven, but you must follow DefinitelyTyped rules and keep a separate package under
@types/.
Preparation checklist: what to gather before you type
- Official SDK docs, changelogs, and JavaScript examples.
- Runtime artifacts: UMD bundles, minified bundles, or native SDK headers (for mobile).
- API surface map: constructors, factory functions, classes, events, callback signatures, and streaming endpoints.
- Test samples from real apps, if available—these help validate edge cases.
- Licensing and contribution policy to choose DefinitelyTyped or upstream. When in doubt about legal and licensing impacts, consult a technical legal audit guide like How to Audit Your Legal Tech Stack.
Tooling & workflow: what actually ships typed code
Use a lightweight, repeatable workflow so you can test types across TypeScript versions and CI. Typical toolset:
- TypeScript (install multiple versions for CI matrix)
- tsd for writing assertion tests (preferred today for many projects)
- dtslint historically used by DefinitelyTyped—check the current DT contribution guide for the latest requirement.
- types-publisher (for DefinitelyTyped contributions)
- CI (GitHub Actions) to run
tscandtsdacross versions — consider automating CI/CD security and maintenance steps similar to pipeline automation writeups like Automating Virtual Patching: Integrating 0patch-like Solutions into CI/CD.
Example minimal test setup (package.json snippets):
{
"devDependencies": {
"typescript": "^5.5.0",
"tsd": "^0.26.0"
},
"scripts": {
"test:types": "tsd"
}
}
Patterns for robust, maintainable type definitions
When typing an SDK, focus on stable, minimal contracts first—users value autocompletion and safe defaults. Use these patterns:
- Prefer explicit interfaces for public options and models; they’re extensible.
- Use generics for typed responses (e.g.,
Client.query<Row>()). - Model events with strongly-typed overloads or discriminated unions rather than loose
any. - Fallbacks: when an SDK returns dynamic JSON, type as
unknownand provide narrowing helpers. - Declaration merging is useful for adding global augmentation or plugin systems common in mapping SDKs.
Example: ClickHouse Node client (simplified)
ClickHouse clients often support typed query results and streaming. Here’s a compact declaration to get you started.
declare module "clickhouse-client" {
export interface ClickHouseOptions {
url: string;
username?: string;
password?: string;
database?: string;
timeout?: number;
}
export interface QueryResult> {
rows: Row[];
rowsAffected?: number;
}
export class ClickHouseClient {
constructor(options: ClickHouseOptions);
query>(sql: string, params?: any[]): Promise>;
streamQuery>(sql: string, onRow: (row: Row) => void): Promise;
close(): Promise;
}
export function createClient(options: ClickHouseOptions): ClickHouseClient;
}
Usage example that benefits from types:
import { createClient } from "clickhouse-client";
const client = createClient({ url: process.env.CLICKHOUSE_URL! });
interface EventRow { id: number; event_type: string; payload: any }
const res = await client.query("SELECT id, event_type, payload FROM events LIMIT 10");
res.rows.forEach(r => console.log(r.event_type));
Example: mapping SDK types (web SDK)
Mapping SDKs expose init options, map methods, and an event bus. Model events clearly to help integrations.
declare module "super-map-sdk" {
export interface MapInitOptions {
container: HTMLElement | string;
center?: [number, number];
zoom?: number;
style?: string;
}
export type MapEvent =
| { type: "click"; lngLat: [number, number]; target: string }
| { type: "load" }
| { type: "moveend" };
export class Map {
constructor(opts: MapInitOptions);
on(event: MapEvent["type"], handler: (e: MapEvent) => void): void;
addMarker(id: string, lngLat: [number, number]): void;
removeMarker(id: string): void;
getCenter(): [number, number];
}
export function createMap(opts: MapInitOptions): Map;
}
Example: mobile assistant / AI SDK (client-side)
AI or assistant SDKs often mix sync config, async streaming responses, and typed intents. Here’s a compact surface:
declare module "mobile-assistant-sdk" {
export interface AssistantConfig {
apiKey?: string;
sessionId?: string;
model?: string;
locale?: string;
}
export type Intent = { name: string; confidence: number; slots?: Record };
export interface AssistantResponse {
text?: string;
intent?: Intent;
payload?: T;
error?: { code: string; message: string };
}
export class AssistantClient {
constructor(config: AssistantConfig);
send(text: string): Promise>;
stream(text: string, onChunk: (chunk: AssistantResponse) => void): Promise;
on(event: "connected" | "disconnected" | "error", cb: (arg?: any) => void): void;
}
export function createAssistant(config: AssistantConfig): AssistantClient;
}
Testing types: tools and patterns
Type tests (not runtime tests) assert that your types produce the intended compile-time results. Use tsd to write tests like:
import { expectType } from "tsd";
import { createClient } from "clickhouse-client";
const client = createClient({ url: "http://localhost" });
expectType>(client.query("SELECT 1"));
Run tests across TypeScript versions in CI. Sample GitHub Action matrix:
strategy:
matrix:
ts: [4.9, 5.3, 5.6]
steps:
- run: npm ci
- run: npm run test:types # uses the local typescript version from the matrix
DefinitelyTyped contribution flow (practical steps)
- Fork the DefinitelyTyped repo and clone it locally.
- Create a folder under
types/named after the npm package (e.g.,clickhouse-client). - Add an
index.d.ts,tsconfig.json, andtsd-test.ts(the tests). - Follow the repo lint rules—run
npm run lintandnpm testlocally. - Open a PR and provide real-world examples and migration notes in the description.
Note: DefinitelyTyped maintains strict review practices—explain assumptions and include test cases for edge behavior.
Working with SDK owners: ship first-party types
When the upstream maintainer is responsive, propose a small, incremental PR:
- Start with minimal types for public API functions and the most-used classes.
- Include usage examples in the README and a minimal test harness.
- Offer to maintain initial patches, or propose a co-maintenance model via a types folder and MAP to semantic releases.
Pro tip: vendor adoption of type definitions increases install conversions. Show maintainers that types reduce their issue volume from TypeScript users.
Versioning, compatibility and maintenance
Types should follow the package’s semver. For DefinitelyTyped:
- Publish one major version per breaking change.
- Keep tests for historical TypeScript versions if the library supports them.
Automate maintenance with:
- CI tests on PRs across TypeScript versions.
- Dependabot for types devDeps.
- A contributor guide inside the types folder explaining assumptions, versions covered, and test commands.
Practical PR checklist (copyable)
- Include API surface in README examples.
- Add
index.d.tswith clear comments and credits. - Write
tsdtests for critical patterns and edge cases. - Run a local lint and test suite across TS versions.
- Document which runtime behaviors are not typed (e.g., dynamic JSON payloads).
- Link to upstream docs and include version mapping.
Case studies & 2026 predictions
ClickHouse’s strong funding rounds in 2024–2025 pushed ClickHouse into more product stacks. Community-contributed types for ClickHouse clients shortened the path from PoC to production in several analytics teams. Similarly, after Apple’s integration choices for mobile assistants (leveraging Gemini technology) surfaced new closed SDK patterns, community type packages helped early adopters integrate assistant features without waiting for vendor types. For discussions comparing LLM behaviors and safety tradeoffs that influence how you model streaming responses, see analyses like Gemini vs Claude Cowork and vendor-specific writeups such as Siri + Gemini: What Developers Need to Know.
Predictions for the near future (2026):
- SDKs that ship first-party TypeScript types will be preferred by enterprise buyers—typed SDKs reduce integration risk.
- AI SDKs will push more streaming, typed event models; types that model partial responses and streaming chunks will be crucial.
- DefinitelyTyped will remain vital for closed or slow-to-ship vendors, but more vendors will accept PRs for first-party types to control developer experience.
Final actionable takeaways
- Start small: type the most-used functions and add tests—don’t try to type every private edge case in the first PR.
- Use tsd: write assertion tests and run them across a TypeScript-version matrix in CI.
- Prefer first-party when possible: submit a minimal PR to upstream and explain the user benefits (fewer issues, better DX).
- Submit to DefinitelyTyped: when upstream is closed or unresponsive; follow the repo’s lint and test rules.
- Document assumptions: state runtime behaviors you could not verify (e.g., dynamic JSON) so users understand typing boundaries.
Where to go next
If you want a template to get started, clone a community starter repo (search for @types/starter) or use the examples above to scaffold an index.d.ts, tests, and CI. Contributing types is high-leverage: a small PR can unblock dozens of teams and reduce runtime errors across production stacks.
Want a hand? Help the ecosystem—pick one of these next steps:
- Open a GitHub issue on an SDK requesting types and propose a minimal PR.
- Fork DefinitelyTyped and practice by creating types for a small client you use daily (mapping SDK, ClickHouse client, or AI SDK).
- Share your PR in the TypeScript community channels and ask for a quick review—people want to help improve type coverage.
Ready to contribute? Start by forking a repo and submitting a tiny PR that types one function. You’ll earn gratitude from hundreds of TypeScript users and dramatically reduce integration risk for your team.
Related Reading
- Siri + Gemini: What Developers Need to Know About the Google-Apple AI Deal
- Gemini vs Claude Cowork: Which LLM Should You Let Near Your Files?
- Storage Considerations for On-Device AI and Personalization (2026)
- Automating Virtual Patching: Integrating 0patch-like Solutions into CI/CD and Cloud Ops
- Memory Shortages at CES: How Rising Module Prices Affect Developer Workstations
- Turn Your Child's Favorite Game into Keepsakes: 3D-Printed Pokémon and MTG Accessories
- Streamer Safety Checklist: Protecting Your Accounts After the LinkedIn/Facebook/Instagram Takeover Wave
- Best Executor Builds After the Nightreign Patch
- Games Should Never Die? How Devs, Publishers, and Communities Can Keep MMOs Alive
Related Topics
Unknown
Contributor
Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.
Up Next
More stories handpicked for you
Enhancing Type Safety in Microservices: A Guide with TypeScript
Interview Prep: TypeScript Challenges Inspired by Real‑World Problems (Maps, LLMs, Embedded)
Optimizing TypeScript Performance: Insights from the OpenAI ChatGPT Atlas Browser
Career Guide: Skills to Lead TypeScript Projects That Integrate AI, Edge, and Analytics
Exploring Mobile Game Development with TypeScript: Insights from Civilization VII
From Our Network
Trending stories across our publication group