Typescript, özellik türünü sadece T yerine T | Properties["key"] olarak varsayar
Diyelim ki şöyle bir tür tanımladık:
type PropsBase<T> = {
optionalProp?: T;
}
type Props<T, TAdditionalProps extends object> = PropsBase<T> & TAdditionalProps
Temelde ortak bir özellikler nesnem var ve sonra alt sınıflar ihtiyaç duyarlarsa bazı ek özellikler ekleyebilir. Sonra bunu şöyle kullanmak istiyorum:
type State<T> = {
value: T;
}
abstract class Base<T, TAdditional extends object = {}> {
state: State<T>;
constructor(props: Readonly<Props<T, TAdditional>>) {
this.state = {
value: props.optionalProp || this.fallbackValue() // ERROR!
}
}
abstract fallbackValue(): T;
}
Bu, aşağıdaki hataya neden olur:
TS2322: Type 'T | Props<T, TAdditional>["optionalProp"]' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to
'T | Props<T, TAdditional>["optionalProp"]'.
Eğer optionalProp'u isteğe bağlı olmaktan çıkarırsam (?'yi kaldırırsam) o zaman çalışıyor, ayrıca constructor'dan Readonly'u kaldırıp sadece Props<T, TAdditional> kullanırsam da çalışıyor.
Yani sorum şu: neden bu oluyor? ve burada Readonly kullanmaya devam ederek isteğe bağlı bir özellik sahibi olmanın bir yolu var mı?
P.S. tsconfig.json dosyamda strict: true var. Biliyorum, eğer bunu false yaparsam çalışacak.
Cevap #1
Bence || yerine ?? kullanmak sorununuzu çözer.
Oyun alanı
type PropsBase<T> = {
optionalProp?: T;
}
type Props<T, TAdditionalProps extends object> = PropsBase<T> & TAdditionalProps
type State<T> = {
value: T;
}
abstract class Base<T, TAdditional extends object = {}> {
state: State<T>;
constructor(props: Readonly<Props<T, TAdditional>>) {
this.state = {
value: props.optionalProp ?? this.fallbackValue()
}
}
abstract fallbackValue(): T;
}
Cevap #2
Evet, sıkı mod çok iyi çalışmıyor. Ama kullanma nedenim strictBindCallApply ve strictNullChecks'di. Yani cevabım şu - özelliği özelliğe ayarlayın:
{
"compilerOptions": {
"strictBindCallApply": true,
"strictNullChecks": true
}
}
