@@ -522,7 +522,16 @@ class TsGenerator : public BaseGenerator {
522522 case BASE_TYPE_BOOL:
523523 return value.constant == " 0" ? " false" : " true" ;
524524
525- case BASE_TYPE_STRING:
525+ case BASE_TYPE_STRING: {
526+ // NOTE: Strings without a default value are parsed as "0" by
527+ // the parser, so therefore we have to treat "0" as a null-signifying
528+ // value.
529+ if (value.constant == " 0" || value.constant == " null" ) {
530+ return " null" ;
531+ } else {
532+ return " \" " + value.constant + " \" " ;
533+ }
534+ }
526535 case BASE_TYPE_UNION:
527536 case BASE_TYPE_STRUCT: {
528537 return null_keyword_;
@@ -1334,10 +1343,9 @@ class TsGenerator : public BaseGenerator {
13341343 // Emit a scalar field
13351344 const auto is_string = IsString (field.value .type );
13361345 if (IsScalar (field.value .type .base_type ) || is_string) {
1337- const auto has_null_default = is_string || HasNullDefault (field);
1338-
1339- field_type += GenTypeName (imports, field, field.value .type , false ,
1340- has_null_default);
1346+ field_type +=
1347+ GenTypeName (imports, field, field.value .type , false ,
1348+ !HasDefaultValue (field) || HasNullDefault (field));
13411349 field_val = " this." + namer_.Method (field) + " ()" ;
13421350
13431351 if (field.value .type .base_type != BASE_TYPE_STRING) {
@@ -1731,21 +1739,22 @@ class TsGenerator : public BaseGenerator {
17311739 offset_prefix = " const offset = " + GenBBAccess () +
17321740 " .__offset(this.bb_pos, " +
17331741 NumToString (field.value .offset ) + " );\n " ;
1734- offset_prefix += " return offset ? " ;
1742+ offset_prefix += " return " ;
17351743 }
17361744
17371745 // Emit a scalar field
17381746 const auto is_string = IsString (field.value .type );
17391747 if (IsScalar (field.value .type .base_type ) || is_string) {
1740- const auto has_null_default = is_string || HasNullDefault (field);
1748+ const auto has_null_default =
1749+ !field.IsRequired () && !HasDefaultValue (field);
17411750
17421751 GenDocComment (field.doc_comment , code_ptr);
17431752 std::string prefix = namer_.Method (field) + " (" ;
17441753 if (is_string) {
1745- code += prefix + " ):string|" + null_keyword_ + " \n " ;
1754+ code += prefix + " ):" + (has_null_default ? " string|" + null_keyword_ : " string " ) + " \n " ;
17461755 code +=
17471756 prefix + " optionalEncoding:flatbuffers.Encoding" + " ):" +
1748- GenTypeName (imports, struct_def, field.value .type , false , true ) +
1757+ GenTypeName (imports, struct_def, field.value .type , false , has_null_default ) +
17491758 " \n " ;
17501759 code += prefix + " optionalEncoding?:any" ;
17511760 } else {
@@ -1774,9 +1783,16 @@ class TsGenerator : public BaseGenerator {
17741783 if (is_string) {
17751784 index += " , optionalEncoding" ;
17761785 }
1777- code +=
1778- offset_prefix + GenGetter (field.value .type , " (" + index + " )" );
1779- if (field.value .type .base_type != BASE_TYPE_ARRAY) {
1786+ if (field.IsRequired ()) {
1787+ code +=
1788+ offset_prefix + GenGetter (field.value .type , " (" + index + " )" );
1789+ ;
1790+ } else {
1791+ code += offset_prefix + " offset ? " +
1792+ GenGetter (field.value .type , " (" + index + " )" );
1793+ }
1794+ if (field.value .type .base_type != BASE_TYPE_ARRAY &&
1795+ !field.IsRequired ()) {
17801796 code += " : " + GenDefaultValue (field, imports);
17811797 }
17821798 code += " ;\n " ;
@@ -1801,8 +1817,8 @@ class TsGenerator : public BaseGenerator {
18011817 code +=
18021818 MaybeAdd (field.value .offset ) + " , " + GenBBAccess () + " );\n " ;
18031819 } else {
1804- code += offset_prefix + " (obj || " + GenerateNewExpression (type) +
1805- " ).__init(" ;
1820+ code += offset_prefix + " offset ? (obj || " +
1821+ GenerateNewExpression (type) + " ).__init(" ;
18061822 code += field.value .type .struct_def ->fixed
18071823 ? " this.bb_pos + offset"
18081824 : GenBBAccess () + " .__indirect(this.bb_pos + offset)" ;
@@ -1960,7 +1976,7 @@ class TsGenerator : public BaseGenerator {
19601976 code += " ):" + vectortypename + " |" + null_keyword_ + " {\n " ;
19611977
19621978 if (vectortype.base_type == BASE_TYPE_STRUCT) {
1963- code += offset_prefix + " (obj || " +
1979+ code += offset_prefix + " offset ? (obj || " +
19641980 GenerateNewExpression (vectortypename);
19651981 code += " ).__init(" ;
19661982 code += vectortype.struct_def ->fixed
@@ -1973,7 +1989,8 @@ class TsGenerator : public BaseGenerator {
19731989 } else if (IsString (vectortype)) {
19741990 index += " , optionalEncoding" ;
19751991 }
1976- code += offset_prefix + GenGetter (vectortype, " (" + index + " )" );
1992+ code += offset_prefix + " offset ? " +
1993+ GenGetter (vectortype, " (" + index + " )" );
19771994 }
19781995 code += " : " ;
19791996 if (field.value .type .element == BASE_TYPE_BOOL) {
@@ -2005,7 +2022,7 @@ class TsGenerator : public BaseGenerator {
20052022 " "
20062023 " {\n " ;
20072024
2008- code += offset_prefix +
2025+ code += offset_prefix + " offset ? " +
20092026 GenGetter (field.value .type , " (obj, this.bb_pos + offset)" ) +
20102027 " : " + null_keyword_ + " ;\n " ;
20112028 break ;
@@ -2058,7 +2075,7 @@ class TsGenerator : public BaseGenerator {
20582075 // Emit a length helper
20592076 GenDocComment (code_ptr);
20602077 code += namer_.Method (field, " Length" );
2061- code += " ():number {\n " + offset_prefix;
2078+ code += " ():number {\n " + offset_prefix + " offset ? " ;
20622079
20632080 code +=
20642081 GenBBAccess () + " .__vector_len(this.bb_pos + offset) : 0;\n }\n\n " ;
@@ -2069,15 +2086,30 @@ class TsGenerator : public BaseGenerator {
20692086 GenDocComment (code_ptr);
20702087
20712088 code += namer_.Method (field, " Array" );
2072- code += " ():" + GenType (vectorType) + " Array|" + null_keyword_ +
2073- " {\n " + offset_prefix;
2074-
2075- code += " new " + GenType (vectorType) + " Array(" + GenBBAccess () +
2076- " .bytes().buffer, " + GenBBAccess () +
2077- " .bytes().byteOffset + " + GenBBAccess () +
2078- " .__vector(this.bb_pos + offset), " + GenBBAccess () +
2079- " .__vector_len(this.bb_pos + offset)) : " + null_keyword_ +
2080- " ;\n }\n\n " ;
2089+
2090+ std::string return_type =
2091+ (field.IsRequired () || HasDefaultValue (field))
2092+ ? " Array"
2093+ : (" Array|" + null_keyword_);
2094+ if (field.IsRequired ()) {
2095+ code += " ():" + GenType (vectorType) + return_type + " {\n " +
2096+ offset_prefix + " new " + GenType (vectorType) + " Array(" +
2097+ GenBBAccess () + " .bytes().buffer, " + GenBBAccess () +
2098+ " .bytes().byteOffset + " + GenBBAccess () +
2099+ " .__vector(this.bb_pos + offset), " + GenBBAccess () +
2100+ " .__vector_len(this.bb_pos + offset));\n }\n\n " ;
2101+ } else {
2102+ std::string value = HasDefaultValue (field)
2103+ ? " new " + GenType (vectorType) + " Array()"
2104+ : " null" ;
2105+ code += " ():" + GenType (vectorType) + return_type + " {\n " +
2106+ offset_prefix + " offset ? new " + GenType (vectorType) +
2107+ " Array(" + GenBBAccess () + " .bytes().buffer, " +
2108+ GenBBAccess () + " .bytes().byteOffset + " + GenBBAccess () +
2109+ " .__vector(this.bb_pos + offset), " + GenBBAccess () +
2110+ " .__vector_len(this.bb_pos + offset)) : " + value +
2111+ " ;\n }\n\n " ;
2112+ }
20812113 }
20822114 }
20832115 }
@@ -2308,6 +2340,34 @@ class TsGenerator : public BaseGenerator {
23082340 return field.IsOptional () && field.value .constant == " null" ;
23092341 }
23102342
2343+ static bool HasDefaultValue (const FieldDef& field) {
2344+ switch (field.value .type .base_type ) {
2345+ // These types can't have defaults
2346+ case BASE_TYPE_UNION:
2347+ case BASE_TYPE_STRUCT: {
2348+ return false ;
2349+ }
2350+
2351+ // Arrays always have a default (empty array)
2352+ case BASE_TYPE_ARRAY:
2353+ return true ;
2354+
2355+ // The only supported default for vectors is []
2356+ case BASE_TYPE_VECTOR:
2357+ return field.value .constant == " []" ;
2358+
2359+ // Even strings are presumed to be null-default if the default value is
2360+ // "0", this is intended behavior.
2361+ case BASE_TYPE_STRING: {
2362+ return field.value .constant != " 0" && field.value .constant != " null" ;
2363+ }
2364+
2365+ default : {
2366+ return field.value .constant != " null" ;
2367+ }
2368+ }
2369+ }
2370+
23112371 std::string GetArgType (import_set& imports, const Definition& owner,
23122372 const FieldDef& field, bool allowNull) {
23132373 return GenTypeName (imports, owner, field.value .type , true ,
0 commit comments