diff --git a/src/internal/abi/type.go b/src/internal/abi/type.go
index 598c919d0c87cbdc4a08b1bcf08f9c9a6fec8a78..df61400923859f624b1293c43e82ebed66cf69ad 100644
--- a/src/internal/abi/type.go
+++ b/src/internal/abi/type.go
@@ -177,6 +177,15 @@ func TypeOf(a any) *Type {
 	return (*Type)(NoEscape(unsafe.Pointer(eface.Type)))
 }
 
+// TypeFor returns the abi.Type for a type parameter.
+func TypeFor[T any]() *Type {
+	var v T
+	if t := TypeOf(v); t != nil {
+		return t // optimize for T being a non-interface kind
+	}
+	return TypeOf((*T)(nil)).Elem() // only for an interface kind
+}
+
 func (t *Type) Kind() Kind { return t.Kind_ & KindMask }
 
 func (t *Type) HasName() bool {
diff --git a/src/unique/clone_test.go b/src/unique/clone_test.go
index 69a9a540c07fa0a7ed3e49c3b5ca10d4e8d7419d..b0ba5b312e1466dbfba5166d092e94dae1b489fd 100644
--- a/src/unique/clone_test.go
+++ b/src/unique/clone_test.go
@@ -27,7 +27,7 @@ func cSeq(stringOffsets ...uintptr) cloneSeq {
 
 func testCloneSeq[T any](t *testing.T, want cloneSeq) {
 	typName := reflect.TypeFor[T]().Name()
-	typ := abi.TypeOf(*new(T))
+	typ := abi.TypeFor[T]()
 	t.Run(typName, func(t *testing.T) {
 		got := makeCloneSeq(typ)
 		if !reflect.DeepEqual(got, want) {
diff --git a/src/unique/handle.go b/src/unique/handle.go
index 0842ae3185f2ccef5619eb79b6bae9af461f3d2f..96d8fedb0cabe6c519feab9132d1731f2b18f748 100644
--- a/src/unique/handle.go
+++ b/src/unique/handle.go
@@ -31,7 +31,7 @@ func (h Handle[T]) Value() T {
 // are equal if and only if the values used to produce them are equal.
 func Make[T comparable](value T) Handle[T] {
 	// Find the map for type T.
-	typ := abi.TypeOf(value)
+	typ := abi.TypeFor[T]()
 	ma, ok := uniqueMaps.Load(typ)
 	if !ok {
 		// This is a good time to initialize cleanup, since we must go through
diff --git a/src/unique/handle_test.go b/src/unique/handle_test.go
index dffe10ac728189b04e57413c66e7d12a9ec42a3e..b031bbf6852c6b33051ce4ecdfb4ff2fae8fd977 100644
--- a/src/unique/handle_test.go
+++ b/src/unique/handle_test.go
@@ -41,6 +41,7 @@ func TestHandle(t *testing.T) {
 		s: [2]testStringStruct{testStringStruct{"y"}, testStringStruct{"z"}},
 	})
 	testHandle[testStruct](t, testStruct{0.5, "184"})
+	testHandle[testEface](t, testEface("hello"))
 }
 
 func testHandle[T comparable](t *testing.T, value T) {
@@ -93,7 +94,7 @@ func drainMaps(t *testing.T) {
 
 func checkMapsFor[T comparable](t *testing.T, value T) {
 	// Manually load the value out of the map.
-	typ := abi.TypeOf(value)
+	typ := abi.TypeFor[T]()
 	a, ok := uniqueMaps.Load(typ)
 	if !ok {
 		return