Typed Context Keys with Generics

Store request-scoped values in context.Context with generic key types so lookups are type-safe and cannot collide by string.

GoResilience

Code

snippet
package main

import (
	"context"
	"fmt"
)

type key[T any] struct{ name string }

func WithValue[T any](ctx context.Context, k key[T], value T) context.Context {
	return context.WithValue(ctx, k, value)
}

func Value[T any](ctx context.Context, k key[T]) (T, bool) {
	value, ok := ctx.Value(k).(T)
	return value, ok
}

type RequestID string

var requestIDKey = key[RequestID]{name: "request-id"}

func main() {
	ctx := WithValue(context.Background(), requestIDKey, RequestID("req-42"))
	id, ok := Value(ctx, requestIDKey)
	fmt.Println(id, ok)

	_, missing := Value(ctx, key[int]{name: "attempt"})
	fmt.Println("missing:", missing)
}