Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion sdk/core/core-tracing/review/core-tracing.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export interface OperationTracingOptions {
tracingContext?: TracingContext;
}

// @public
export type Resolved<T> = T extends {
then(onfulfilled: infer F): any;
} ? F extends (value: infer V) => any ? Resolved<V> : never : T;

// @public
export type SpanStatus = SpanStatusSuccess | SpanStatusError;

Expand Down Expand Up @@ -57,7 +62,7 @@ export interface TracingClient {
withContext<CallbackArgs extends unknown[], Callback extends (...args: CallbackArgs) => ReturnType<Callback>>(context: TracingContext, callback: Callback, ...callbackArgs: CallbackArgs): ReturnType<Callback>;
withSpan<Options extends {
tracingOptions?: OperationTracingOptions;
}, Callback extends (updatedOptions: Options, span: Omit<TracingSpan, "end">) => ReturnType<Callback>>(name: string, operationOptions: Options, callback: Callback, spanOptions?: TracingSpanOptions): Promise<ReturnType<Callback>>;
}, Callback extends (updatedOptions: Options, span: Omit<TracingSpan, "end">) => ReturnType<Callback>>(name: string, operationOptions: Options, callback: Callback, spanOptions?: TracingSpanOptions): Promise<Resolved<ReturnType<Callback>>>;
}

// @public
Expand Down
1 change: 1 addition & 0 deletions sdk/core/core-tracing/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
Instrumenter,
InstrumenterSpanOptions,
OperationTracingOptions,
Resolved,
SpanStatus,
SpanStatusError,
SpanStatusSuccess,
Expand Down
14 changes: 13 additions & 1 deletion sdk/core/core-tracing/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* A narrower version of TypeScript 4.5's Awaited type which Recursively
* unwraps the "awaited type", emulating the behavior of `await`.
*/
export type Resolved<T> = T extends { then(onfulfilled: infer F): any } // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
? F extends (value: infer V) => any // if the argument to `then` is callable, extracts the first argument
? Resolved<V> // recursively unwrap the value
: never // the argument to `then` was not callable
: T; // non-object or non-thenable

/**
* Represents a client that can integrate with the currently configured {@link Instrumenter}.
*
Expand All @@ -12,6 +22,8 @@ export interface TracingClient {
*
* This is the primary interface for using Tracing and will handle error recording as well as setting the status on the span.
*
* Both synchronous and asynchronous functions will be awaited in order to reflect the result of the callback on the span.
*
* Example:
*
* ```ts
Expand All @@ -32,7 +44,7 @@ export interface TracingClient {
operationOptions: Options,
callback: Callback,
spanOptions?: TracingSpanOptions
): Promise<ReturnType<Callback>>;
): Promise<Resolved<ReturnType<Callback>>>;
/**
* Starts a given span but does not set it as the active span.
*
Expand Down
5 changes: 3 additions & 2 deletions sdk/core/core-tracing/src/tracingClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import {
OperationTracingOptions,
Resolved,
TracingClient,
TracingClientOptions,
TracingContext,
Expand Down Expand Up @@ -64,14 +65,14 @@ export function createTracingClient(options: TracingClientOptions): TracingClien
operationOptions: Options,
callback: Callback,
spanOptions?: TracingSpanOptions
): Promise<ReturnType<Callback>> {
): Promise<Resolved<ReturnType<Callback>>> {
const { span, updatedOptions } = startSpan(name, operationOptions, spanOptions);
try {
const result = await withContext(updatedOptions.tracingOptions!.tracingContext!, () =>
Promise.resolve(callback(updatedOptions, span))
);
span.setStatus({ status: "success" });
return result;
return result as ReturnType<typeof withSpan>;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed in TS 4.4 see playground link but for reasons unknown to me TS4.2 infers the returntype of this as unknown

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing the playground!

} catch (err) {
span.setStatus({ status: "error", error: err });
throw err;
Expand Down