TS: Como usar genéricos

TS: Genérico

1. Introdução

  • Às vezes, se quisermos fazer com que os parâmetros e tipos de retorno de uma função sejam iguais, podemos usar variáveis ​​de tipo .

  • Uma variável de tipo é um tipo especial de variável usado para representar um tipo em vez de um valor.

    function identity<T>(arg : T) : T{
          
          
        return arg;
    }
    
  • Depois que a função genérica é definida, ela pode ser usada de duas maneiras.

  • Uma é passar todos os parâmetros, incluindo os parâmetros de tipo:

    let out = identity<string>("yivi");
    
  • A outra é usar a inferência de tipo, ou seja, o compilador inferirá automaticamente o tipo:

    let out = identity("yivi");
    
  • A inferência de tipo nos ajuda a manter o código conciso e altamente legível.

2. Variáveis ​​genéricas

  • Vamos dar uma olhada em um exemplo:

    function foo<T>(arg : T): T{
          
          
        console.log(arg.length);	// error,arg的类型为T,无明确指示方法,因此报错。
        return arg;
    }
    
  • Quando queremos manipular um array do tipo T, .lengtha propriedade existe, então nenhum erro será relatado:

    function foo<T>(args : T[]):T[]{
          
          
        console.log(args.length);
        return args;
    }
    
    // or
    
    function foo<T>(args : Array<T>) : Array<T>{
          
          
        console.log(args.length);
        return args;
    }
    

3. Tipos genéricos

  • Podemos usar diferentes nomes de parâmetros genéricos, desde que o número e o uso sejam consistentes;

  • Você também pode usar literais de objeto com assinaturas de chamada para definir funções genéricas;

    function identity<T>(arg : T) : T{
          
          
        return arg;
    }
    
    let myIdentity : <U>(arg : U) => U = identity;
    
    // or 
    
    let myIdentity : {
          
          <T>(arg : T):T} = identity;
    
  • Pegue o objeto literal acima e escreva-o como uma interface:

    interface IdentityInterface{
          
          
        <T>(arg : T) : T;
    }
    
    function identity<T> (arg : T) : T{
          
          
        return arg;
    }
    
    let myidentity : IdentityInterface = identity;
    
  • Também é possível tratar um parâmetro genérico como um parâmetro de toda a interface, de modo a garantir que sabemos qual tipo genérico está sendo usado:

    interface IdentityInterface<T>{
          
          
        (arg : T) : T;
    }
    
    function identity<T> (arg : T) : T{
          
          
        return arg;
    }
    
    let myidentity : IdentityInterface<string> = identity;
    
  • As classes genéricas são semelhantes às interfaces genéricas e ambas usam <> para restrições:

    class Foo<T>{
          
          
        state : T;
        add : (x : T, y : T) => T;
    }
    
    let myfoo = new Foo<number>();
    myfoo.state = 1;
    myfoo.add = (x,y)=>{
          
          
        return x + y;
    }
    

4. Restrições genéricas

  • No exemplo acima, mencionamos .lengthque se este atributo for usado em genéricos, um erro será relatado;

  • Portanto, precisamos apenas implementar uma interface e permitir que o tipo genérico tenha esse atributo para evitar que o compilador relate erros;

    interface Length{
          
          
        length : number;
    }
    
    function identity<T extends Length>(arg : T) : T{
          
          
        console.log(arg.length);
        return arg;
    }
    
  • Embora o compilador não relate um erro, se você usar um tipo sem esse atributo, ele também relatará um erro;

  • Portanto, precisamos passar um valor que atenda às restrições e contenha os atributos necessários;

    identity({
          
          length : 10,value : 100});
    

5. Use tipos de classe em genéricos

  • Ao usar genéricos para criar funções de fábrica no TypeScript, você precisa se referir ao tipo de classe do construtor.

    function create<T> (c : {
          
          new() : T}) : T{
          
          
        return new c();
    }
    
    class Foo{
          
          
        name : string;
    }
    
    let a : Foo = create(Foo);
    a.name = 'yivi'
    console.log(a.name)
    

Acho que você gosta

Origin blog.csdn.net/yivisir/article/details/109560081
Recomendado
Clasificación