Bağımsız değişken olarak iletilen TypeScript nesnesi için varsayılan değeri ayarlama


198
function sayName(params: {firstName: string; lastName?: string}) {
    params.lastName = params.lastName || 'smith';  // <<-- any better alternative to this?
    var name = params.firstName + params.lastName
    alert(name);
}

sayName({firstName: 'bob'});

Bunun işe yarayabileceğini hayal etmiştim:

function sayName(params: {firstName: string; lastName: string = 'smith'}) {

Açıkçası bunlar açık argümanlarsa, bunu şu şekilde yapabilirsiniz:

function sayName(firstName: string, lastName = 'smith') {
    var name = firstName + lastName;
    alert(name);
}

sayName('bob');

Ve coffeescript'te koşullu varlık operatörüne erişebilirsiniz, böylece şunları yapabilirsiniz:

param.lastName ?= 'smith'

Hangi javascript derler:

if (param.lastName == null) {
    param.lastName = 'smith';
}

Önerilen çözüm params.lastName = params.lastName || 'smith';aslında gayet iyi - boş dizeleri, tanımsız dizeleri ve boş değerleri işliyor.
Fenton

@SteveFenton Ve sahte bir şey. Soyadı söz konusu olduğunda iyidir, ancak genellikle iyi bir fikir değildir. İşte bu yüzden daktilo metinleri varsayılan değerleri çevirir if(typeof x === "undefined") { … }. Bunu bilmediğiniz için değil, sadece OP'nin genel durumunu işaret ediyoruz.
Ingo Bürk

1
@ IngoBürk doğrudur, ancak lastName?: stringSteveFenton'un "boş dizeleri, tanımsız dizeleri ve null değerleri işlediğini" söylediği gibi olabilir.
AJP

@AJP Daktilo yazısı içinde, evet. Ama bu sadece derleme zamanı. Her iki durumda da, dediğim gibi, sadece genel bir vaka senaryosuna işaret ediyor :)
Ingo Bürk

2
Burada steve ile aynı fikirde. Oldukça yaygın olarak, örneğin 10 argüman yerine tek bir yapılandırma argümanına sahip olmak daha iyidir. Bu durumda params.lastName = params.lastName || 'smith';kullandığım desen
basarat

Yanıtlar:


211

Aslında, şimdi basit bir yol var gibi görünüyor. Aşağıdaki kod TypeScript 1.5'te çalışır:

function sayName({ first, last = 'Smith' }: {first: string; last?: string }): void {
  const name = first + ' ' + last;
  console.log(name);
}

sayName({ first: 'Bob' });

İşin püf noktası, ilk olarak bağımsız değişken nesnesinden hangi anahtarları seçmek istediğinizi parantez içine key=valuealmaktır. Bunu :ve tür bildirimiyle izleyin .

Bu, yapmaya çalıştığınız şeyden biraz farklıdır, çünkü sağlam bir paramsnesneye sahip olmak yerine, bunun yerine değiştirilmiş olmayan değişkenleriniz vardır.

İşleve herhangi bir şey iletmeyi isteğe bağlı yapmak istiyorsanız ?, türdeki tüm anahtarlar için a ekleyin ={}ve tür bildiriminden sonra varsayılan değerini ekleyin :

function sayName({first='Bob',last='Smith'}: {first?: string; last?: string}={}){
    var name = first + " " + last;
    alert(name);
}

sayName();

Bu çözüm , parametreleri tamamen tahrip edildiğini gösteren interetsting kod ipucu / intellisense özelliği sağlar. Bu stili, örnekteki gibi birkaç parametreden daha fazlasına sahip bir ayarlar nesnesinde görmeyi beklemezdim.
WiredPrairie

3
Bunun yerine "sayNameSettings" gibi bir arabirim / sınıf kullanmak için bu çözümü yeniden yazmak da mümkün müdür?
Stef Heyenrath

4
Bu işe yararken, argümanları bu şekilde yok etmek IMO'yu takip etmeyi zorlaştırır.
PW Kad

1
{first = 'Bob', last = 'Smith'} gibi 'as' anahtar kelimesini (bence daha okunabilir) kullanabilirsiniz; {first ?: string olarak; last ?: string} ama ideal olarak bu durumları ele almak için bir arayüz oluşturmalısınız ...
Frohlich

1
Options nesnesini başka bir işleve geçirmenin bir yolu var mı?
Dylanthepiguy

53

Dakik şimdi varsayılan parametreleri destekler:

https://www.typescriptlang.org/docs/handbook/functions.html

Ayrıca, varsayılan bir değer eklemek, varsayılan değerden çıkarılabileceği için tür bildirimini atlamanıza olanak tanır:

function sayName(firstName: string, lastName = "Smith") {
  const name = firstName + ' ' + lastName;
  alert(name);
}

sayName('Bob');

22
Bu, OP'nin bağımsız değişken olarak geçirilen TypeScript nesnesi için varsayılan değerle ilgili sorusuna nasıl uygulanır? Nesne bağımsız değişkenli bir örnek göstermelisiniz.
demisx

9
Öyle değil, ama genel olarak daktiloda varsayılan parametreleri nasıl sağladığımı ararken bu soruyu buldum ve cevapların hiçbiri bunu ele almadı. Ben de ince "nesne" param açıklama fark etmeden önce bu yanıtı yayınladı.
18'de

29

Parametre nesnesini yok eden nesne, yukarıdaki cevapların çoğunun amaçladığı şeydir ve şimdi Typecript, okumayı ve sezgisel olarak daha kolay anlaşılmasını sağlayacak yöntemlere sahiptir.

Yıkımla İlgili Temel Bilgiler: Bir nesneyi yok ederek, bir nesneden anahtar adına göre özellikler seçebilirsiniz. İstediğiniz özelliklerden az veya çok sayıda tanımlayabilirsiniz ve varsayılan değerler, temel bir sözdizimi ile ayarlanır let {key = default} = object.

let {firstName, lastName = 'Smith'} = myParamsObject;

//Compiles to:
var firstName = myParamsObject.firstName, 
_a = myParamsObject.lastName, 
lastName = _a === void 0 ? 'Smith' : _a;

Parametre nesnesi için bir arabirim, tür veya sınıf yazmak okunabilirliği artırır.

type FullName = {
  firstName: string;
   
  /** @default 'Smith' */
  lastName ? : string;
}

function sayName(params: FullName) {

  // Set defaults for parameter object
  var { firstName, lastName = 'Smith'} = params;

  // Do Stuff
  var name = firstName + " " + lastName;
  alert(name);
}

// Use it
sayName({
  firstName: 'Bob'
});


3
Bu sorunun en iyi cevabı olduğunu düşünüyorum!
Gezim

24

Hayır, TypeScript, birinin varsayılanı diğerinin olmadığı gibi tanımlanmış bir nesnenin özellikleri için varsayılanları ayarlamanın doğal bir yolu yoktur. Daha zengin bir yapı tanımlayabilirsiniz:

class Name {
    constructor(public first : string, 
        public last: string = "Smith") {

    }
}

Ve bunu satır içi tür tanımı yerine kullanın.

function sayName(name: Name) {
    alert(name.first + " " + name.last);
}

Ne yazık ki böyle bir şey yapamazsınız:

function sayName(name : { first: string; last?:string } 
       /* and then assign a default object matching the signature */  
       = { first: null, last: 'Smith' }) {

} 

Sadece varsayılan kuracak gibi eğer nameidi undefined.


Bence bu soruya verilecek en iyi cevap bu ve doğru cevap olarak işaretlenmesi gerekiyor.
kapad

16

Bu, uzun yapıcılar içermeyen bunu yapmanın güzel bir yolu olabilir

class Person {
    firstName?: string = 'Bob';
    lastName?: string = 'Smith';

    // Pass in this class as the required params
    constructor(params: Person) {
        // object.assign will overwrite defaults if params exist
        Object.assign(this, params)
    }
}

// you can still use the typing 
function sayName(params: Person){ 
    let name = params.firstName + params.lastName
    alert(name)
}

// you do have to call new but for my use case this felt better
sayName(new Person({firstName: 'Gordon'}))
sayName(new Person({lastName: 'Thomas'}))

2
@PWKad varsayılanlar ikinci ve üçüncü satır olan "Bob" ve "Smith" olarak ayarlanmıştır
Cameron

3

İşte arayüzü kullanarak ve varsayılan değerlerle yıkım denemek için bir şey. Lütfen "lastName" in isteğe bağlı olduğunu unutmayın.

interface IName {
  firstName: string
  lastName?: string
}

function sayName(params: IName) {
  const { firstName, lastName = "Smith" } = params
  const fullName = `${firstName} ${lastName}`

  console.log("FullName-> ", fullName)
}

sayName({ firstName: "Bob" })

0

Yıkmadan, varsayılan parametreler oluşturabilir ve içeri aktarabilirsiniz

interface Name {
   firstName: string;
   lastName: string;
}

export const defaultName extends Omit<Name, 'firstName'> {
    lastName: 'Smith'
}

sayName({ ...defaultName, firstName: 'Bob' })
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.