Skip to content

Add support for template default types #5407

@simPod

Description

@simPod

If template is impossible to resolve, eg. because the type is T|null, it should be possible to specify a default type

Consider this: If a value passed for $a is null, it's impossible to resolve TResult's type. Then default type should be used. Currently, the default type everywhere is mixed instead.

/**
 * @template T
 */
interface I {
	/**
	 * @template TResult
	 * @param (callable(T): TResult)|null $a
	 * @return I<TResult>
	 */
  public function work(callable|null $a = null): I;
}

It should be possible to say that TResult default is T. Therefore, when calling work(null) on I<string>, the return type would be string.

https://psalm.dev/r/254659fcc2


This feature is already present in other languages like typescript or java

interface I<T>
{
    work<TResult = T>(a: ((value: T) => TResult) | null): TResult;
}
interface Promise<T> {
   then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions